2010-08-02 2 views
5

Шнуровка скомпилировать следующую программу с Visual Studio 10, я получаю много ошибок компиляции:Проблема с станд :: make_tuple в C++ 0x

#include "stdafx.h" 

#include <tuple> 
#include <string> 
#include <map> 
#include <iostream> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    typedef std::tuple<std::string, std::string> key_t; 
    typedef std::map<key_t, std::string> map_t; 

    map_t the_map; 

    auto k = std::make_tuple("one", "two"); 
    the_map[k] = "the value"; 

    auto q = std::make_tuple("one", "two"); 

    auto i = the_map.find(q); 
    std::cout << i->second << std::endl; 

    return 0; 
} 

Ошибка 1 Ошибка C2664: «зЬй :: basic_string < _Elem, _Traits, _Ax> :: basic_string (const std :: basic_string < _Elem, _Traits, _Ax> &) ': невозможно преобразовать параметр 1 из' const key_t 'в' const std :: basic_string < _Elem, _Traits, _Ax > & 'c: \ program files (x86) \ microsoft visual studio 10.0 \ vc \ include \ tuple 127 1 кортеж

Исходя из линии:

std::cout << i->second << std::endl; 

Странная вещь есть, как минимум, с моей точки зрения, если я меняю эти строки:

auto k = std::make_tuple("one", "two"); 
the_map[k] = "the value"; 

в

the_map[std::make_tuple("one", "two")] = "p"; 

в компиляции программ. Итак, мой вопрос, конечно, почему? Я предполагаю, что это что-то делать с make_tuple и двигаться семантику - но я не понимаю, что ..

ответ

4

Видимо, ошибка происходит на самом деле от линии the_map[k] = "the value";

При использовании оператора [] на карте, библиотека пытается создать объект std::pair<Key,Value>. В вашем случае это будет std::pair<std::tuple<std::string,std::string>,std::string>.

Однако, если вы используете промежуточную переменную k, конструктор станд :: пары, которая называется это: (копия-вставили из стандартного Lib)

_Pair_base(const _Ty1x& _Val1, _Ty2x&& _Val2) 
     : first(_Val1), second(_STD move(_Val2)) 
     { // construct from specified values 
     } 

Этот конструктор пытается сделать копию ваш key_t. К сожалению, кортеж реализации MSVC++ прослушивается на данный момент, и копия не скомпилируется (см. Также: C++0x : are tuples of tuples allowed?)

Я могу диагностировать больше, потому что эта реализация не только прослушивается, но и очень сложна.

Корпорации Boost должны работать, но не имеют оператора <, поэтому вы не можете их использовать.

«Наилучшее» решение на данный момент, чтобы написать the_map.insert(std::make_pair(k, "the value"));

+0

Спасибо - это работает, и мой оригинальный код будет выглядеть хорошо с вашим исправлением. – baardk

+0

Обратите внимание, что вы также можете написать 'the_map [std :: move (k)] =" значение "', но это «уничтожит» вашу переменную 'k' (посмотрите на некоторые статьи о семантике перемещения, если вы не видите, что Я имею в виду уничтожить). – Tomaka17

+0

Ницца. Я опубликовал проблему на каком-то сайте MS connect, поэтому они могут проверить, является ли это ошибкой или чем-то. – baardk

2

Это похоже на ошибку в VS10, по какой-то причине он пытается бросить тип ключа для типа значения.

Эта упрощенная версия также терпит неудачу.

typedef std::map<std::tuple<int, int>, int> map_t; 

map_t the_map; 

map_t::key_type k = std::make_tuple(1,2); 
the_map[k] = 3; 

Производит следующее:

ошибка C2440: 'инициализации': не может конвертировать из 'сопзЬ станд :: tr1 :: кортеж < _Arg0, _Arg1>' на 'Int'

+0

А, приятное упрощение. – baardk

Смежные вопросы