8

在 C++98 中,我通常使用以下语句在迭代器的值类型中声明一个变量:

typename std::iterator_traits<Iterator>::value_type value;

在 C++11 中,我们有 decltype,我认为推断值类型的最简单方法是:

decltype(*iterator) value;

不幸的是,对于大多数迭代器,*iterator 的类型是 value_type& 而不是 value_type。任何想法,没有类型修改类,如何将上述内容按摩成产生 value_type (而不是任何参考)?


我不认为这个问题是不合理的,因为以下内容相当稳健但最终创建了另一个变量。

auto x = *iterator;
decltype(x) value;

另请注意,我真的想要推导的类型而不仅仅是一个实例,例如,如果我想声明这些值的 std::vector。

4

2 回答 2

17

继续使用iterator_traitsdecltype(*iterator)甚至可以是某种奇怪的代理类,以便在表达式中做一些特殊的事情*iter = something

例子:

#include <iostream>
#include <iterator>
#include <typeinfo>
#include <vector>

template <typename T>
void print_type()
{
    std::cout << typeid(T).name() << std::endl;
}

template <typename Iterator>
void test(Iterator iter)
{
    typedef typename
        std::iterator_traits<Iterator>::value_type iter_traits_value;

    auto x = *iter;
    typedef decltype(x) custom_value;

    print_type<iter_traits_value>();
    print_type<custom_value>();
}

int main()
{
    std::vector<int> a;
    std::vector<bool> b;

    test(a.begin());
    test(b.begin());
}

MSVC 2012 上的输出:

int
int
bool
class std::_Vb_reference<struct std::_Wrap_alloc<class std::allocator<unsigned int>>>

他们不一样。

于 2013-03-22T01:02:19.430 回答
1

对于这个用例,我喜欢 std::decay。通常我会使用

std::vector< int > vec;
using value_type = typename std::decay< decltype(*begin(vec)) >::type; 
static_assert(std::is_same< int, value_type >::value, "expected int");
于 2013-03-22T17:45:29.010 回答