2017-10-18 13 views
4

자동 차별화 라이브러리 Adept를 사용하려고하는데 gcc 4.9.0 및 icc 16.0.2와 작동하지만 VS 2017 및 Clang 4.0.1에서는 실패했습니다.오류 : 'EndIndex'에 'rank_'멤버가 없습니다.

다음 코드 조각으로 문제를 줄였습니다. 지식을 얻기 위해 라이브러리 작성자와 문제를 해결하는 동안이 코드가 두 컴파일러에서 작동하고 실패하는 이유를 알고 싶습니다. 다른 두 사람을 짓는다. VS 2017에 대한

template <typename A> 
struct Expression 
{ 
    static const int rank = A::rank_; 
}; 

struct EndIndex : public Expression<EndIndex> 
{ 
    static const int rank_ = 0; 
}; 

int main(int argc, char ** argv) 
{ 
    return 0; 
} 

출력은 다음과 같습니다 연타 4.0.1에 대한

1>------ Build started: Project: Test, Configuration: Debug Win32 ------ 
1>Source.cpp 
1>d:\Test\source.cpp(4): error C2039: 'rank_': is not a member of 'EndIndex' 
1>d:\Test\source.cpp(7): note: see declaration of 'EndIndex' 
1>d:\Test\source.cpp(8): note: see reference to class template instantiation 'Expression<EndIndex>' being compiled 
1>d:\Test\source.cpp(4): error C2065: 'rank_': undeclared identifier 
1>d:\Test\source.cpp(4): error C2131: expression did not evaluate to a constant 
1>d:\Test\source.cpp(4): note: failure was caused by non-constant arguments or reference to a non-constant symbol 
1>d:\Test\source.cpp(4): note: see usage of 'rank_' 
1>Done building project "Test.vcxproj" -- FAILED. 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

그리고 출력 :

source.cpp:4:37: error: no member named 'rank_' in 'EndIndex' 
           static const int rank = A::rank_; 
                 ~~~^ 
source.cpp:7:38: note: in instantiation of template class 'Expression<EndIndex>' requested here 
                 struct EndIndex : public Expression<EndIndex> 
+0

나는 다른 CRTP 질문에서 찾고 있던 답을 찾을 일이. [link] (https://stackoverflow.com/questions/46576847/clang-vs-gcc-crtp-constexpr-variable-cannot-have-non-literal-type/46578880#46578880) –

답변

3

아마도 그 단계에서 rank_이 정의되지 않았기 때문에 발생합니다. 애플 LLVM 버전 9.0.0 (연타-900.0.38)를위한

다음 수정 사항이 :

template <typename A> 
struct Expression 
{ 
    static const int rank; 
}; 

struct EndIndex : public Expression<EndIndex> 
{ 
    static const int rank_ = 0; 
}; 

template <typename A> 
const int Expression<A>::rank = A::rank_; 
+0

이 제안은 VS 2017. –

+0

@ ManuelNúñez, 그것을 확인해 주셔서 감사합니다! –

0

비주얼 C++와 그 소리가이기 때문에 EndIndexrank_ 멤버를 찾을 수 단순히 없습니다 선언되기 전에 액세스됩니다. 이러한 멋진 코드는 종종 일부 환경에서 문제를 일으 킵니다.