2017-11-08 9 views
3

OSX (clang) 및 Linux (GCC/Clang)에서 올바르게 컴파일되는 라이브러리를 빌드하려고합니다. MSVC/Visual Studio 2017에서 이해할 수없는 템플릿 정의를 발견했습니다. 다음과 같은 오류가MSVC : 인식 할 수없는 템플릿 선언/정의 (Clang/GCC로 컴파일)

#include "stdafx.h" 

template<class T> 
class Parent { 
    class Child { 
     friend class Parent; 
    public: 
     Child(const Child &r); 
    }; 
}; 

template<class T> 
Parent<T>::Child::Child(const Parent<T>::Child &r) { 
    *this = r; 
} 

int main(int argc, char const *argv[]) { 
    /* code */ 
    return 0; 
} 

이 (여전히) 결과 : 나는 그것을로 요약 할 수

1>...consoleapplication1.cpp(13): error C2988: unrecognizable template declaration/definition 
1>...consoleapplication1.cpp(13): error C2059: syntax error: '(' 
1>...consoleapplication1.cpp(13): error C2143: syntax error: missing ';' before '{' 
1>...consoleapplication1.cpp(13): error C2447: '{': missing function header (old-style formal list?) 

하지만 (여전히) 연타 또는 GCC와 OSX에 컴파일합니다. stdafx.hmain은 실제 라이브러리 코드의 일부가 아니지만 VS Windows 명령 줄 프로젝트에서이 코드를 사용할 수 있도록 추가되었습니다.

무엇이 여기에 있습니까? MSVC는 템플릿의 멤버 클래스 또는 친구 선언에 문제가 있습니까?

+1

[This] (https://godbolt.org/g/ZnwTFm)가 문제를 해결합니다. 그중 하나가 틀린 것 같습니다. –

+0

@PasserBy :'const Parent :: Child'를'const * typename * Parent :: Child'로 변경하면 실제로 문제가 해결됩니다. 또한이 매우 유용한 온라인 컴파일러를 보여 주셔서 대단히 감사합니다. 나는 미래에 문제가 생길 때 그것을 확실히 사용할 것입니다. – aleneum

답변

2

VC++의 문제는 매개 변수 유형이 typename으로 제한되지 않는다는 것입니다. [temp.res]/7 :

[…] within the definition of a member of a class template following the declarator-id, the keyword typename is not required when referring to the name of a previously declared member of the class template that declares a type or a class template.

선언자-ID가선언의 첫번째 요소이다 파라미터 절에 따라서 모든 부재 유형 typename 접두사 될 필요는 없다.

+0

명확히하기 위해, 후행 형식이 아닌 리턴 유형은 _declarator-id?가 있기 때문에'typename'을 필요로합니다. –

+0

@PasserBy 그래, 우리가 왼쪽에서 오른쪽으로 해석하기 때문에 이해가된다. 그래서 우리는 더 잘 알 수 없었다. – Columbo