std :: result_of应用于const重载方法

时间:2017-01-19 16:32:09

标签: c++ static const typedef decltype

如果我给

typedef std::vector<int> v;

然后可以使用下面的方法来捕获常量迭代器的类型(另一种方法是使用v::const_iterator,但这取决于在类中明确定义的const_iterator成员类型。

typedef typename std::result_of<decltype(&v::cbegin)(v*)>::type const_iterator;

事实上,我们可以检查上述内容是否符合我们的要求。

static_assert(std::is_same<const_iterator, typename v::const_iterator>::value);

但是,我发现编译器失败了。

typedef typename std::result_of<decltype(&v::begin)(v*)>::type iterator;

编译器抱怨该方法被重载(通过const修饰符)并且无法明确解析。但是,我找不到解决歧义的语法。至少,人们期望下面的内容是明确的,因为只有const版本可以在const对象上运行。然而,即使是下面也同样存在问题。

typedef typename std::result_of<decltype(&v::begin)(const v*)>::type const_iterator2;

如何引用begin的特定const或nonconst版本?

1 个答案:

答案 0 :(得分:4)

以下是您想要的:

using v = std::vector<int>;
using iter = decltype(std::declval<v>().begin());
static_assert(std::is_same<iter, typename v::iterator>::value);

这里的问题是&v::begin含糊不清。有两个v::begin函数,&运算符无法知道哪一个返回地址。使用std::declval可以解决这个问题。由于std::declval<v>()的返回类型为v,编译器知道您对非const v::begin()感兴趣。

同样,以下内容将为您提供const版本:

using citer = decltype(std::declval<const v>().begin());
static_assert(std::is_same<citer, typename v::contst_iterator>::value);

请注意,此代码中未创建任何对象。 std::declval没有定义,因此它仅适用于decltype等未评估的上下文。