2010-08-02 28 views
5

搭售make_tuple編譯與Visual Studio 10下面的程序,我得到很多的編譯錯誤的:有問題的std :: 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:「的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:\ 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,這就是所謂的std ::對的構造是:(從標準庫複製粘貼)

_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 2010-08-02 12:41:00

+0

請注意,您也可以編寫'the_map [std :: move(k)] =「value」,但這會「銷燬」您的''k'變量(查看一些關於移動語義的文章,如果您沒有看到什麼我的意思是摧毀)。 – Tomaka17 2010-08-02 12:46:36

+0

不錯。我在一些MS連接網站上發佈了這個問題,所以他們可以檢查它是一個錯誤還是什麼。 – baardk 2010-08-02 12:53:41

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: '初始化':不能轉換從 '常量的std :: TR1 ::元組< _Arg0,_Arg1>' 到 '廉政'

+0

啊,很好的簡化。 – baardk 2010-08-02 13:33:02