I have a class parameterized by a template template class with a static member function:
template <template <typename> class F>
struct A {
static int foo();
};
This class has no default definition for foo
, and must be specialized for different types.
I also have another class parameterized by a template template class with a nested template class:
template <template <typename> class F>
struct B {
template <typename T>
struct C {};
};
I want C
to specialize A
for any template template class F
that specializes A
already:
template <template <typename> class F>
struct A<B<F>::template C> {
static int foo();
};
template <template <typename> class F>
int A<B<F>::template C>::foo() {
return A<F>::foo() / 2;
}
So, if I have a class that specializes A
:
template <typename T>
struct E {};
template <>
int A<E>::foo() {
return 42;
}
I would expect to be able to use the specialization like this (and return 21):
int bar() {
return A<B<E>::template C>::foo();
}
However, this fails to link - it cannot find the reference to A<B<E>::C>::foo()
.
(Note that all of this is in a single file - there is nothing weird happening with headers here)
It appears that the compiler is trying to use the primary template for A
rather than the specialization, which means that foo
is undefined. Why does it not use the specialization in this instance?
Full Example
template <template <typename> class F>
struct A {
static int foo();
};
template <template <typename> class F>
struct B {
template <typename T>
struct C {};
};
template <template <typename> class F>
struct A<B<F>::template C> {
static int foo();
};
template <template <typename> class F>
int A<B<F>::template C>::foo() {
return A<F>::foo() / 2;
}
template <typename T>
struct E {};
template <>
int A<E>::foo() {
return 42;
}
int bar() {
// Link fails - error: undefined reference to 'A<B<E>::C>::foo()'
return A<B<E>::template C>::foo();
}