使用 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;
}
Error 1 error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const std::basic_string<_Elem,_Traits,_Ax> &)' : cannot convert parameter 1 from 'const key_t' to 'const std::basic_string<_Elem,_Traits,_Ax> &' c:\program files (x86)\microsoft visual studio 10.0\vc\include\tuple 127 1 tuple
来自行:
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 和移动语义有关 - 但我不明白是什么......
最佳答案
显然错误实际上来自 the_map[k] = "the value";
行
当您在 map 上使用 [] 运算符时,库会尝试创建一个 std::pair<Key,Value>
目的。在你的例子中,这变成了 std::pair<std::tuple<std::string,std::string>,std::string>
.
但是,如果您使用中间变量 k
,调用的 std::pair 的构造函数是:(从标准库复制粘贴)
_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"));
关于c++ - C++0x 中 std::make_tuple 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3387422/