错误:没有名为' rank _'在' EndIndex'

时间:2017-10-18 08:56:06

标签: c++ templates crtp

我正在尝试使用自动差异库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 个答案:

答案 0 :(得分:3)

可能是因为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_;

答案 1 :(得分:0)

Visual C ++和clang根本无法找到rank_的{​​{1}}成员,因为它在声明之前被访问过。这种花哨的代码通常会在某些环境中导致问题。