Следующий фрагмент кода работает с Visual Studio 2008, но не с 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_;
};
использование
typedef std::tr1::tuple<int, int> MyValueType;
MyStruct<MyValueType> a;
MyValueType x;
a.set(x);
Я получаю следующую ошибку:
1> C: \ Program Files \ Microsoft Visual Studio 10.0 \ VC \ include \ tuple (127):
ошибка C2440: «инициализация»: невозможно преобразовать из «const MyValueType»
в ‘int’ 1> Пользовательский оператор преобразования недоступен
который может выполнить это преобразование, или оператор не может быть вызван 1>
C: \ Program Files \ Microsoft Visual Studio 10.0 \ VC \ include \ xxtuple0 (9):
см. ссылку на создание шаблона функции
«Станд :: tr1 :: _ Cons_node<_Car, _Cdr> :: _ Cons_node<_Ty, станд :: tr1 :: _ Nil&, Станд :: tr1 :: _ Nil&, Станд :: tr1 :: _ Nil&, Станд :: tr1 :: _ Nil&, Станд :: tr1 :: _ Nil&, Станд :: tr1 :: _ Nil&, Станд :: tr1 :: _ Nil&, Станд :: tr1 :: _ Nil&, Станд :: tr1 :: _ Nil&> (_ Farg0
&&, _Farg1, _Farg2, _Farg3, _Farg4, _Farg5, _Farg6, _Farg7, _Farg8, _Farg9)»
компилируется 1> с 1> [1>
_Car = int, 1> _Cdr = std :: tr1 :: _ Cons_node :: _ Type>,
1> _Ty = MyValueType, 1> _Farg0 = MyValueType,
1> _Farg1 = std :: tr1 :: _ Nil &, 1>
_Farg2 = станд :: 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): см. Ссылку на создание экземпляра шаблона функции ‘std :: tr1 :: tuple<_Arg0, _Arg1> :: кортеж> (_ Farg0 &&) компилируется 1>
с 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): при компиляции функции-члена шаблона класса ‘std :: _ Pair_base<_Ty1, _Ty2> :: _ Pair_base (Const
станд :: tr1 :: кортеж<_Arg0, _Arg1> &&, внутр &&) ‘1> с 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)
: см. ссылку на создание шаблона класса
«Станд :: _ Pair_base<_Ty1, _Ty2> ‘компилируется 1> с 1>
[1> _Ty1 = const MyValueType, 1> _Ty2 = int 1>
] 1>
D: \ Projekte \ демо \ Demo.cpp (40)
: см. ссылку на создание шаблона класса ‘std :: pair<_Ty1, _Ty2>»
компилируется 1> с 1> [1>
_Ty1 = const MyValueType, 1> _Ty2 = int 1>] 1> D: \ Projekte \ demo \ Demo.cpp (39)
: при компиляции функции-члена шаблона класса ‘void
MyStruct :: набор (TKey &) ‘1> с 1> [1>
TKey = MyValueType 1>] 1>
D: \ Projekte \ демо \ Demo.cpp (92)
: см. ссылку на создание экземпляра шаблона класса MyStruct
скомпилировано 1> с 1> [1>
TKey = MyValueType 1>] 1> C: \ Program Files \ Microsoft Visual
Studio 10.0 \ VC \ include \ tuple (127): ошибка C2439:
«Станд :: tr1 :: _ Cons_node<_Car, _Cdr> :: _ Value ‘: член не может быть
инициализированный 1> с 1> [1> _Car = int,
1>
_Cdr = станд :: tr1 :: _ Cons_node :: _ Type>
1>] 1> C: \ Program Files \ Microsoft Visual Studio
10.0 \ VC \ include \ tuple (170): см. Объявление ‘std :: tr1 :: _ Cons_node<_Car, _Cdr> :: _ Value ‘1> с 1>
[1> _Car = int, 1>
_Cdr = станд :: tr1 :: _ Cons_node :: _ Type>
1>] ========== Построение: 0 выполнено, 1 не выполнено, 0 обновлено, 0 пропущено ===========
Если заменить typedef std :: tr1 :: tuple MyValueType на typedef int MyValueType, это работает.
Заранее спасибо.
Я думаю, что это ошибка, связанная с неправильной реализацией семантики перемещения в MSVC 2010, поскольку вы можете успешно скомпилировать этот код:
typename Keys::value_type v( key, 1 );
keys_.insert(v);
Других решений пока нет …