I have a template struct and I want that every pointer type instantiates the const version, to avoid having duplicate templates. This doesn't work, but it work with the char pointer. How can I make it work with any pointer?
#include <iostream>
template<class T>
struct Foo {
static void bar() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
// Doesn't work
// template<class T>
// struct Foo<T*> : Foo<const T*> {};
// Works
template<>
struct Foo<char*> : Foo<const char*> {};
int main() {
Foo<char*>::bar();
}
CodePudding user response:
Since T
can also be T const
, you are creating infinite inheritance, hence the incomplete type error.
Since const T*
matches T*
with T
being char const
for example, you makes the class inheriting from itself be inheriting from Foo<T const*>
, which expands to Foo<char const const*>
which collapses to Foo<char const*>
.
Simply add a constraint and your code works as expected:
// Now works
template<class T> requires (not std::is_const_v<T>)
struct Foo<T*> : Foo<const T*> {};
CodePudding user response:
You can do it if you extract a base class from Foo
:
#include <iostream>
template<class T>
struct FooImpl {
static void bar() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
template<class T>
struct Foo : FooImpl<T> {};
template<class T>
struct Foo<T*> : FooImpl<const T*> {};
int main() {
Foo<char*>::bar();
Foo<const char*>::bar();
}
Unlike @Guillaume answer, this does not require C 20.