Проблема с std :: make_tuple в C ++ 0x - PullRequest
5 голосов
/ 02 августа 2010

При попытке компилировать следующую программу с помощью Visual Studio 10 я получаю множество ошибок компиляции:

#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: 'std :: 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: \ программные файлы(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 и семантикой перемещения, но я не понимаю, что ..

Ответы [ 2 ]

5 голосов
/ 02 августа 2010

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

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

Однако, если вы используете промежуточную переменную k, конструктор std :: pair, который вызывается: (скопированный из стандартной lib)

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

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

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

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

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

2 голосов
/ 02 августа 2010

Это похоже на ошибку в 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: «инициализация»: невозможно преобразовать из «const std :: tr1 :: tuple <_Arg0, _Arg1>» в «int»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...