Ошибка: нет члена с именем rank_ в EndIndex
Я пытаюсь использовать библиотеку автоматического дифференцирования Adept, и я заставил ее работать с gcc 4.9.0 и icc 16.0.2, но не удалось с VS 2017 и Clang 4.0.1
Я сократил проблему до следующего фрагмента и, пока я решаю эту проблему с создателями библиотеки, ради знаний я хотел бы знать, почему этот фрагмент кода работает в двух упомянутых компиляторах и не встраивается в другие два.
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;
}
Выход для VS 2017:
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 ==========
И вывод для Clang 4.0.1:
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>
2 ответа
Это, вероятно, происходит потому, что rank_
не определен на этом этапе.
Следующее исправляет это для Apple LLVM версии 9.0.0 (clang-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_;
Visual C++ и clang просто не могут найти rank_
член EndIndex
потому что к нему обращаются до того, как объявлено. Такой причудливый код часто приводит к проблемам в некоторых средах.