C ++ 0x中std :: make_tuple的问题

时间:2010-08-02 11:51:05

标签: c++ visual-studio-2010 c++11

为了使用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&lt; _Elem,_Traits,_Ax&gt; :: basic_string(const std :: basic_string&lt; _Elem,_Traits,_Ax&gt;&amp;)':无法从'const key_t'转换参数1到'const std :: basic_string&lt; _Elem,_Traits,_Ax&gt; &安培;” 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和移动语义有关 - 但我不明白是什么..

2 个答案:

答案 0 :(得分:5)

显然,错误来自行the_map[k] = "the value";

在地图上使用[]运算符时,库会尝试创建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的元组应该有效,但没有&lt;运算符,所以你不能使用它们。

目前“最佳”解决方案是撰写the_map.insert(std::make_pair(k, "the value"));

答案 1 :(得分: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:'初始化':无法转换为'const std :: tr1 :: tuple&lt; _Arg0,_Arg1&gt;'到'int'