Это интересный случай! Моя позиция, будь то компилятор или стандартная проблема, похожа на @lubgr, но я хотел бы добавить еще несколько идей.
У ICC также есть некоторые проблемы с вашей конструкцией, из-за чего можно предположить, что это более глубоко укоренилось в стандарте (тем не менее, gcc здесь может быть правильным). Ошибка завершается ошибкой: «список аргументов шаблона должен соответствовать списку параметров» - это может означать, что для обоих компиляторов это:
template<typename FOO>
template<typename Foo<FOO>::Value VALUE>
не идентичны оригинальному определению Foo
. Кажется, это ошибка обоих компиляторов, но я научился быть осторожным, когда два разных компилятора имеют общие проблемы.
Извлечение определения Value
из исходного шаблона в отдельный шаблон исправляет регистр ( код в Compiler Explorer ):
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; }
Вы также можете это исправить, просто используя жестко закодированный тип Value
( код в Compiler Explorer ) - но, вероятно, это не то, что вам нужно:
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; }
Надеюсь, это поможет!