5
votes

The following code snippet work with Visual Studio 2008 but not with Visual Studio 2010.

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_;
};

Usage

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

I get following error:

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 ==========

If a replace typedef std::tr1::tuple MyValueType with typedef int MyValueType it works.

Thank you in advance.

1
Seems to be a compiler bug, it compiles on gcc. You are missing typename before Keys::value_type (since value_type depends on TKey); but adding that doesn't fix the error either.Praetorian
Usually, I use keys_.insert(std::make_pair(key, 1)); for such inserts. This should always work.Olaf Dietsche
Oh, yes I forgot the typename. I extracted MyStruct from I third-party library that I used in my project. There has the typename. So I fix the sample above.mar.na
The problem lies with value_type being pair<K const, V> and it seems MSVC's implementation of pair doesn't correctly move from const qualified members.Xeo

1 Answers

2
votes

I think this is an error that related to bad implementation of move semantic in MSVC 2010 since you can successfully compile this code:

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