2013-03-22 81 views
7

聲明一個迭代的值在C++ 98,我通常使用以下中的迭代器的值類型聲明變量:如何通過decltype

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

在C++ 11我們有decltype和我原以爲來推斷該值類型的最簡單的方法是:

decltype(*iterator) value; 

不幸的是,大多數迭代器,迭代器的*類型是VALUE_TYPE &,而不是VALUE_TYPE。任何想法,沒有類型修改類,如何按摩以上產生value_type(而不是任何參考)?


我不認爲這個問題是不合理的,因爲以下是相當強大的,但最終創建另一個變量。

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

另外請注意,我真正想要的推導型並不僅僅是一個實例例如如果我想聲明這些值的std :: vector。

+0

類型表達的'* iterator'被'的std :: iterator_traits :: reference',不'value_type'。這不一定是'value_type&','decltype'可能會根據它的值類別報告表達式的類型與實際不同。 – 2013-03-22 05:42:17

+0

如果你只是想結合你的編輯的兩行,相當於'typename std :: decay :: type value;',但是看看下面的答案, t做到這一點:)我只是把這個添加爲['std :: decay'](http://en.cppreference.com/w/cpp/types/decay)在這個Q/A中沒有提到過。 – 2013-03-22 07:47:54

回答

15

繼續使用iterator_traitsdecltype(*iterator)甚至可能是某種奇怪的代理類,以便在表達式*iter = something中執行特殊操作。

實施例:2012年MSVC

#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()); 
} 

輸出:

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

他們不一樣。

+0

但正如我在我的編輯中提到的,以下工作:auto x = * iterator; decltype(x)值; – 2013-03-22 01:18:05

+3

@GlenLow:你還沒有定義「作品」。看到我的編輯答案(aschepler,編輯,請你)。 – GManNickG 2013-03-22 01:33:12

+1

+1 for @ GManNickG的編輯。 ; - ] – ildjarn 2013-03-22 01:57:20

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"); 
+0

感謝您的建議,它確實有效(並且我學到了一些新的東西!),但是當我已經有Iterator的類型時,它不會比'std :: iterator_traits :: value_type'冗長。 – 2013-03-23 04:23:28

+0

爲真。 iterator_traits <>是要走的路。我實際上更多地使用我的建議,例如,我有一個未知的容器類型。如果你已經有了迭代器類型,那你肯定是對的。 – 2013-03-23 20:52:05

+0

我應該注意到,這個表達式可能不適用於迭代器的引用類型是一些不正常的代理,就像上面提到的'std :: vector '專業化。 – 2013-03-25 00:03:40