2016-08-05 3 views
5

앞으로 선언을 다음과 왜 같이앞으로 선언

template<typename T> struct std::hash; 

는 GCC와 그 소리와 함께 컴파일에 실패하지만 2015 비주얼 스튜디오로 컴파일?

GCC 6.1.0 (사용 coliru) :

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

그 소리 3.8.0 (사용 coliru는) :

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

그것은 VS (http://webcompiler.cloudapp.net/)에서 작동합니다. 어느 컴파일러가 옳은가?

btw. 동일한 선언이 C++ Primer 5 판에서 사용됩니다. 대체로 struct : template <class T> class std::hash; 대신에 class을 사용하는 것과 거의 같습니다.

전체 코드 : 앞으로 선언이 많은 일반 선언 같은 기능을하기 때문에

#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

GCC 또는 Clang으로 컴파일되지 않지만 MSVC로 컴파일되는 경우 MSVC는 일반적으로 잘못되었습니다. –

+0

^MSVC는 표준 준수 코드를 파싱 할 때 본질적으로 나쁜 것으로 알려져 있습니다. –

+0

AFAIK 네임 스페이스 표준을 확장하는 것이 금지되어 있습니다. – alain

답변

1

이유는 크게 것으로 보인다. 즉, 하나의 접두사가없는 네임 스페이스에 포함됩니다. 나는 이것이 동일한 파서가 선언과 전달 선언에 사용되는 것을 가능하게한다고 생각한다.