2013-03-22 17 views
7

üzerinden bir yineleyici değerini beyan nasıl C++ 11'indeC++ 98, ben genellikle bir yineleyici değer türü bir değişken bildirmek için aşağıdaki kullanmak ise decltype

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

biz decltype var ve Ben değer türü anlamak için en kolay yolu düşünmüştü: çoğu yineleyiciler için maalesef

decltype(*iterator) value; 

, yineleyici * tipi value_type & ve VALUE_TYPE değildir. Herhangi bir fikir, tip modifikasyon sınıfları olmadan, yukarıdakilere nasıl değer verileceğini (value_type) (ve herhangi bir referans değil)?


ben soru şu oldukça sağlamdır ama başka bir değişken oluşturarak biter mantıksız verilir sanmıyorum.

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

Ayrıca ben gerçekten örneğin çıkar sanan tip istiyorum ve sadece bir örneği dikkat Bu değerlerin bir std :: vektörünü bildirmek isteseydim.

+0

ifadesinin tipi kullanılarak olurdum typicall '* iterator'' std :: :: reference' değil, 'value_type' iterator_traits edilir. Bu zorunlu olarak "value_type" ve "decltype" ifadesi, gerçekte değer kategorisine bağlı olduğundan farklı bir ifadenin türünü bildirebilir. –

+0

Düzenleme işleminizin iki satırını birleştirmek isterseniz, eşdeğeri 'typename std :: decay :: type value; ', ancak aşağıdaki yanıtlara bakın ve sadece' t yapmak :) Ben sadece daha önce bu Q/A söz konusu değildi ['std :: çürüme '(http://en.cppreference.com/w/cpp/types/decay) olarak ekliyorum. –

cevap

15

iterator_traits ürününü kullanmaya devam edin. decltype(*iterator), *iter = something ifadesinde özel şeyler yapmak için bir çeşit garip proxy sınıfı bile olabilir.

Örnek: MSVC 2012

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

Çıktı:

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

Onlar aynı değil.

+0

Ama benim düzenlememde bahsettiğim gibi, aşağıdaki işler: auto x = * yineleyici; decltype (x) değeri; –

+3

@GlenLow: "İşler" tanımlanmamış. Cevabımdaki cevaba bakın (aschepler, istediğiniz gibi düzenleyin). GManNickG's düzenleme için – GManNickG

+1

+1. ; -] – ildjarn

1

Bu kullanım durumu için std :: decay'i seviyorum. i

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

Öneri için teşekkürler, işe yaradı (ve yeni bir şey öğrendim!) Ama zaten Iterator türüne sahip olduğumda std :: iterator_traits :: value_type'den daha az verbose değil. –

+0

true. iterator_traits <> gitmek için yol vardır. Aslında önerim, örneğin, bilinmeyen bir kapsayıcı türü olduğunda daha fazla kullanıyorum. Yineleyici türünüz varsa, kesinlikle haklısınız. –

+0

Yukarıda belirtilen std :: vector 'uzmanlığında olduğu gibi, yinelemenin referans türünün bir sapık proxy olduğu durumlarda bu ifadenin çalışmayacağını unutmayın. –

İlgili konular