2012-10-22 11 views
5

Il seguente codice di lavoro frammento di con Visual Studio 2008, ma non con Visual Studio 2010.C++ value_type non funzionare per std :: tr1: tupla in uno std :: map

template <typename TKey> 
struct MyStruct 
{ 
    typedef std::map<TKey, int> Keys; 

    MyStruct() 
    { 
    } 

    void set(TKey& key) 
    { 
#if 1 
     // This works with VS 2008 but not with 2010 
     keys_.insert(typename Keys::value_type(key, 1)); 
#else 
     // This works with VS 2008 and VS 2010 
     keys_.insert(std::pair<TKey, int>(key, 1)); 
#endif 
    }; 

private: 
    Keys keys_; 
}; 

Uso

typedef std::tr1::tuple<int, int> MyValueType; 
MyStruct<MyValueType> a; 
MyValueType x; 
a.set(x); 

ottengo l'errore seguente:

1>C:\Program Files\Microsoft Visual Studio 10.0\VC\include\tuple(127): error C2440: 'initializing' : cannot convert from 'const MyValueType' to 'int' 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 1> C:\Program Files\Microsoft Visual Studio 10.0\VC\include\xxtuple0(9) : see reference to function template instantiation 'std::tr1::_Cons_node<_Car,_Cdr>::_Cons_node<_Ty,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&,std::tr1::_Nil&>(_Farg0 &&,_Farg1,_Farg2,_Farg3,_Farg4,_Farg5,_Farg6,_Farg7,_Farg8,_Farg9)' being compiled 1> with 1> [ 1>
_Car=int, 1> _Cdr=std::tr1::_Cons_node::_Type>, 1> _Ty=MyValueType, 1> _Farg0=MyValueType, 1> _Farg1=std::tr1::_Nil &, 1>
_Farg2=std::tr1::_Nil &, 1> _Farg3=std::tr1::_Nil &, 1> _Farg4=std::tr1::_Nil &, 1> _Farg5=std::tr1::_Nil &, 1> _Farg6=std::tr1::_Nil &, 1> _Farg7=std::tr1::_Nil &, 1> _Farg8=std::tr1::_Nil &, 1> _Farg9=std::tr1::_Nil & 1> ] 1> C:\Program Files\Microsoft Visual Studio 10.0\VC\include\utility(145) : see reference to function template instantiation 'std::tr1::tuple<_Arg0,_Arg1>::tuple>(_Farg0 &&)' being compiled 1>
with 1> [ 1> _Arg0=int, 1>
_Arg1=int, 1> _Farg0=const std::tr1::tuple 1> ] 1> C:\Program Files\Microsoft Visual Studio 10.0\VC\include\utility(142) : while compiling class template member function 'std::_Pair_base<_Ty1,_Ty2>::_Pair_base(const std::tr1::tuple<_Arg0,_Arg1> &&,int &&)' 1> with 1>
[ 1> _Ty1=const MyValueType, 1> _Ty2=int, 1> _Arg0=int, 1> _Arg1=int 1> ] 1> C:\Program Files\Microsoft Visual Studio 10.0\VC\include\utility(174) : see reference to class template instantiation 'std::_Pair_base<_Ty1,_Ty2>' being compiled 1> with 1>
[ 1> _Ty1=const MyValueType, 1> _Ty2=int 1> ] 1>
D:\Projekte\demo\Demo.cpp(40) : see reference to class template instantiation 'std::pair<_Ty1,_Ty2>' being compiled 1> with 1> [ 1>
_Ty1=const MyValueType, 1> _Ty2=int 1> ] 1> D:\Projekte\demo\Demo.cpp(39) : while compiling class template member function 'void MyStruct::set(TKey &)' 1> with 1> [ 1>
TKey=MyValueType 1> ] 1>
D:\Projekte\demo\Demo.cpp(92) : see reference to class template instantiation 'MyStruct' being compiled 1> with 1> [ 1>
TKey=MyValueType 1> ] 1>C:\Program Files\Microsoft Visual Studio 10.0\VC\include\tuple(127): error C2439: 'std::tr1::_Cons_node<_Car,_Cdr>::_Value' : member could not be initialized 1> with 1> [ 1> _Car=int, 1>
_Cdr=std::tr1::_Cons_node::_Type> 1> ] 1> C:\Program Files\Microsoft Visual Studio 10.0\VC\include\tuple(170) : see declaration of 'std::tr1::_Cons_node<_Car,_Cdr>::_Value' 1> with 1>
[ 1> _Car=int, 1>
_Cdr=std::tr1::_Cons_node::_Type> 1> ] ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Se una sostituzione typedef std :: tr1 :: tuple MyValueType con typedef int MyValueType funziona.

Grazie in anticipo.

+2

sembra essere un bug del compilatore, si [compila il GCC] (http : //liveworkspace.org/code/a21f9394d98fef376487a2e9ce1fc868). Manca 'typename' prima di' Keys :: value_type' (dato che 'value_type' dipende da' TKey'); ma aggiungendo che non risolve l'errore neanche. – Praetorian

+1

Di solito, uso 'keys_.insert (std :: make_pair (key, 1));' per tali inserti. Questo dovrebbe sempre funzionare. –

+0

Oh, sì, ho dimenticato il nome del tipo. Ho estratto MyStruct dalla libreria di terze parti che ho usato nel mio progetto. C'è il typename. Quindi aggiusto il campione qui sopra. –

risposta

2

credo che questo sia un errore che legato alla cattiva applicazione della mossa semantica in MSVC 2010 in quanto si può compilare correttamente questo codice:

typename Keys::value_type v(key, 1); 
keys_.insert(v); 
+0

Grazie per le risposte veloci. C'è un altro modo per compilare il codice senza cambiare MyStruct. Perché ho estratto MyStruct da una libreria di terze parti (Poco) che ho usato nel mio progetto. –

Problemi correlati