2012-07-10 32 views
8

Với mã bên dưới, tôi gặp lỗi rất khó hiểu trong MSVC dường như gợi ý loại khóa (std :: tuple) đang được chuyển đổi thành tiêu chuẩn: :chuỗi.Sử dụng tiêu chuẩn :: tuple làm khóa cho std :: unordered_map

#include <iostream> 
#include <string> 
#include <tuple> 
#include <utility> 
#include <unordered_map> 

typedef std::tuple<std::string,int,char> key_t; 

struct key_hash : public std::unary_function<key_t, std::size_t> 
{ 
    std::size_t operator()(const key_t& k) const 
    { 
     return std::get<0>(k)[0]^std::get<1>(k)^std::get<2>(k); 
    } 
}; 

struct key_equal : public std::binary_function<key_t, key_t, bool> 
{ 
    bool operator()(const key_t& v0, const key_t& v1) const 
    { 
     return (
       std::get<0>(v0) == std::get<0>(v1) && 
       std::get<1>(v0) == std::get<1>(v1) && 
       std::get<2>(v0) == std::get<2>(v1) 
      ); 
    } 
}; 

struct data 
{ 
    std::string x; 
}; 

typedef std::unordered_map<key_t,data,key_hash,key_equal> map_t; 


int main() 
{ 
    map_t m; 
    data d; 
    d.x = "test data"; 
    m[std::make_tuple("abc",1,'X')] = d; 
    auto itr = m.find(std::make_tuple(std::string("abc"),1,'X')); 
    if (m.end() != itr) 
    { 
     std::cout << "x: " << itr->second.x; 
    } 
    return 0; 
} 

Lỗi:

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 std::tr1::tuple<_Arg0,_Arg1,_Arg2>' to 'const std::basic_string<_Elem,_Traits,_Ax> &' c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\tuple 127 1 

Compiler: MS Visual Studio 2010

On ideone, tôi nhận được sau thậm chí lỗi phức tạp hơn:

http://ideone.com/yEv2j

Tôi có thể' t dường như tìm ra nơi tôi đã đi sai.

+0

Lưu ý rằng bạn không cần phải so sánh các phím như 'std :: get <0> (v0) == std :: lấy <0> (v1) && .....' Thay vào đó bạn chỉ có thể viết 'return v0 = = v1'. – Nawaz

+0

@Nawaz: Cảm ơn nhận xét, tôi đã thử nhưng tôi vẫn gặp lỗi. – Gerdiner

+0

Dòng nào gây ra lỗi, dòng đầu tiên có make_tuple hoặc dòng thứ hai? Lỗi IdeOne cho thấy key_t được định nghĩa lại. Thử đổi tên loại. – Ajay

Trả lời

2

Lạ. Mã của bạn hoạt động tốt trong Visual Studio 2012 RC và đầu ra là "x: dữ liệu thử nghiệm".

+0

Nên làm rõ, tôi đang sử dụng MS visual studio 2010. – Gerdiner

+0

Tại ideone error là /usr/include/sys/types.h:123:17: error: 'key_t' có khai báo trước là 'typedef __key_t key_t ', do đó, nó sẽ làm việc với typedef khác, nhưng tôi không biết về VC 2012. – ForEveR

+0

bạn đúng, tôi thay đổi tên của loại và nó được biên dịch với ideone, có vẻ như có thể có lỗi trong msvc: http://ideone.com/olN9W – Gerdiner

4

Các vấn đề đối với ideone là key_t đã tồn tại:

prog.cpp:7:42: error: conflicting declaration 'typedef class std::tuple<std::basic_string<char>, int, char> key_t' 
/usr/include/sys/types.h:123:17: error: 'key_t' has a previous declaration as 'typedef __key_t key_t' 

Đổi tên của bạn key_t đến cái gì khác, hoặc đặt nó vào một số không gian tên.

Your code works after this change trong cả g ++ và clang ++. Tôi tin rằng đây là một lỗi trong MSVC.

Các vấn đề liên quan