C++ nested template issue

Ank*_*Dev 8 c++ templates g++ language-lawyer clang++

GCC 7.3.1 compile the below code while clang 8.0.0 does not. I would like to know if this syntax is valid (in which case I will report it as a possible clang bug).

Thanks for your help.

template<typename FOO>
struct Foo
{
  using Value = int;

  template<Value VALUE>
  struct Bar;
};

template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
struct Foo<FOO>::Bar { static void test(); };

template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test() {}

int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)

The error message with clang is the following:

error: nested name specifier 'Foo<FOO>::Bar<VALUE>::' for declaration does not refer into a class, class template or class template partial specialization
void Foo<FOO>::Bar<VALUE>::test() {}
     ~~~~~~~~~~~~~~~~~~~~~~^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

EDIT: clang possible bug report here.

Mic*_*Łoś 1

这是一个有趣的案例!无论是编译器问题还是标准问题,我的立场与@lubgr类似,但我想添加更多见解。

ICC 的构造也存在一些问题,这可能表明这在标准中根深蒂固(不过,gcc 在这里可能是正确的)。它失败并出现错误:“模板参数列表必须与参数列表匹配” - 这可能意味着对于两个编译器来说:

template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
Run Code Online (Sandbox Code Playgroud)

与 的原始定义不相同Foo。这似乎是两个编译器的错误,但我学会了当两个不同的编译器遇到类似问题时要小心。

从原始模板中提取定义Value以单独修复这种情况(编译器资源管理器上的代码):

template<typename T>
struct X
{
    using Value = int;
};

template<typename FOO>
struct Foo
{    
  template<typename X<FOO>::Value VALUE>
  struct Bar;
};

template<typename FOO>
template<typename X<FOO>::Value VALUE>
struct Foo<FOO>::Bar { static void test(); };

template<typename FOO>
template<typename X<FOO>::Value VALUE>
void Foo<FOO>::Bar<VALUE>::test() {}

int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)

您也可以通过简单地使用硬编码Value类型(编译器资源管理器上的代码)来解决此问题 - 但这可能不是您需要的:

template<typename FOO>
struct Foo
{    
  template<int VALUE>
  struct Bar;
};

template<typename FOO>
template<int VALUE>
struct Foo<FOO>::Bar { static void test(); };

template<typename FOO>
template<int VALUE>
void Foo<FOO>::Bar<VALUE>::test() {}

int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!