如果我给
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版本?
答案 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
等未评估的上下文。