Рассмотрим следующее:
template<class... T>
struct outer
{
template<int... I>
struct helper{};
template<int Num, class = helper<>>
struct inner;
template<int Num, int... V>
struct inner<Num,helper<V...>> : public inner<Num-1,helper<V...,sizeof...(V)>>{};
template<int... V>
struct inner<0, helper<V...>>{
using type = helper<V...>;
};
};
int main(){
outer<int>::inner<7>::type i;
}
Я обнаружил, что этот код будет компилироваться без ошибок с использованием clang-9.0.1, но не будет работать с использованием g cc -9.2.0 со следующими ошибками:
test2.cpp: In instantiation of ‘struct outer<int>::inner<1, outer<int>::helper<0, 1, 2, 3, 4, 5> >’:
test2.cpp:10:9: recursively required from ‘struct outer<int>::inner<6, outer<int>::helper<0> >’
test2.cpp:10:9: required from ‘struct outer<int>::inner<7>’
test2.cpp:18:22: required from here
test2.cpp:10:9: error: ambiguous template instantiation for ‘struct outer<int>::inner<0, outer<int>::helper<0, 1, 2, 3, 4, 5, 6> >’
10 | struct inner<Num,helper<V...>> : public inner<Num-1,helper<V...,sizeof...(V)>>{};
| ^~~~~~~~~~~~~~~~~~~~~~~
test2.cpp:10:9: note: candidates are: ‘template<class ... T> template<int Num, int ...V> struct outer<T>::inner<Num, outer<T>::helper<V ...> > [with int Num = 0; int ...V = {0, 1, 2, 3, 4, 5, 6}; T = {int}]’
test2.cpp:12:9: note: ‘template<class ... T> template<int ...V> struct outer<T>::inner<0, outer<T>::helper<V ...> > [with int ...V = {0, 1, 2, 3, 4, 5, 6}; T = {int}]’
12 | struct inner<0, helper<V...>>{
| ^~~~~~~~~~~~~~~~~~~~~~
test2.cpp:10:9: error: invalid use of incomplete type ‘struct outer<int>::inner<0, outer<int>::helper<0, 1, 2, 3, 4, 5, 6> >’
10 | struct inner<Num,helper<V...>> : public inner<Num-1,helper<V...,sizeof...(V)>>{};
| ^~~~~~~~~~~~~~~~~~~~~~~
test2.cpp:8:9: note: declaration of ‘struct outer<int>::inner<0, outer<int>::helper<0, 1, 2, 3, 4, 5, 6> >’
8 | struct inner;
| ^~~~~
test2.cpp: In function ‘int main()’:
test2.cpp:18:24: error: ‘type’ is not a member of ‘outer<int>::inner<7>’
18 | outer<int>::inner<7>::type i;
|
Я видел похожее рекурсивное наследование, преуспевающее в g cc, но, похоже, это не так, когда оно находится внутри шаблона класса variadi c. Также следует отметить, что изменение внешнего шаблона на template<class T>
исправляет ошибки g cc.
Это ошибка clang или g cc?