2016-08-05 16 views
5

Tại sao tờ khai chuyển tiếp như sau:Chuyển tiếp tuyên bố std :: băm mẫu chuyên môn

template<typename T> struct std::hash; 

thất bại trong việc biên dịch với gcc và kêu vang, nhưng biên dịch với Visual Studio 2015 không?

gcc 6.1.0 (sử dụng coliru):

main.cpp:11:34: error: invalid use of template-name 'std::hash' without an argument list 
template<typename T> struct std::hash; 
            ^~~~ 

kêu vang 3.8.0 (sử dụng coliru):

main.cpp:11:29: error: forward declaration of struct cannot have a nested name specifier 
template<typename T> struct std::hash; 
          ^~~~~ 

nó hoạt động dưới VS (http://webcompiler.cloudapp.net/). Trình biên dịch nào là đúng?

btw. tuyên bố tương tự được sử dụng trong C++ Primer 5th edition. Vâng - gần giống như vậy nó sử dụng class thay vì struct: template <class T> class std::hash; đó là sai.

mã đầy đủ:

#include <unordered_map> 

/* 
// compiles with gcc,clang,VS 
namespace std { 
    template<typename T> 
    struct hash; 
}*/ 

// Compiles only with VS 
template<typename T> struct std::hash; 

struct MyData { 
    MyData() {} 
    MyData(int d1, int d2) : data1(d1), data2(d2) {} 
    bool operator==(const MyData& rop) const { 
    return rop.data1 == data1 && rop.data2 == data2; 
    } 

    friend struct std::hash<MyData>; 
private: 
    int data1; 
    int data2; 
}; 

namespace std { 
    template<> 
    struct hash<MyData> { 
    typedef MyData argument_type; 
    typedef size_t result_type; 
    size_t operator()(const argument_type& data) const noexcept; 
    }; 

    size_t hash<MyData>::operator()(const argument_type& data) const noexcept { 
    return hash<unsigned>()(data.data1)^hash<unsigned>()(data.data2); 
    } 
} 

int main() { 
    std::unordered_map<MyData, std::string> mm; 
    mm[MyData(1,1)] = "test1"; 
    mm[MyData(2,2)] = "test1"; 
} 
+4

Nếu nó không biên dịch với GCC hoặc Clang nhưng biên dịch với MSVC, MSVC thường sai. –

+0

^MSVC được biết là vốn không hợp lệ khi phân tích mã tuân thủ các tiêu chuẩn. –

+0

AFAIK nó bị cấm mở rộng 'không gian tên std' – alain

Trả lời

1

Lý do, có vẻ là chủ yếu là do một tờ khai phía trước có chức năng giống như một lời tuyên bố thường xuyên. tức là được bọc trong một không gian tên, không được đặt trước bởi một không gian tên. Tôi đoán điều này sẽ cho phép cùng một trình phân tích cú pháp được sử dụng cho các khai báo và các khai báo chuyển tiếp có ý nghĩa.