I have a class template that inherits the constructors of the base class template. (As for c 20) Is there a way to deduce the template arguments of the derived class from the constructor arguments of base?
If I specify the type explicitly, that works. Or if I reimplement the constructor and call the constructor of base, that also would work but is there a way to do without that?
template<typename T>
struct CTestBase
{
using Type = T;
CTestBase() = default;
CTestBase(T t){}
};
template<typename T>
struct CTestDer : public CTestBase<T>
{
using CTestBase<T>::CTestBase;
};
void test()
{
//CTestDer der(int{}); //ERROR
CTestDer<int> der(int{}); //OK
}
CodePudding user response:
You can add a user-defined deduction guide:
#include <utility>
template<typename T>
struct CTestBase
{
using Type = T;
CTestBase() = default;
CTestBase(T t){}
};
template<typename T>
struct CTestDer : public CTestBase<T>
{
using CTestBase<T>::CTestBase;
};
template<typename T>
CTestDer(T &&t) -> CTestDer<std::remove_cvref_t<T>>;
void test()
{
CTestDer der(int{}); // OK now.
}
With a little bit more work it should be possible to:
- Use a variadic template in the deduction guide
- Have the deduction guide use
decltype
to construct, using its own deduction guide, the superclass - Use a specialization to figure out the superclass's template parameters
- Use that to construct the subclass, to deduce it
This should handle anything. But this will be a lot of work. For this simple use case, and if it's not expected that the superclass will change much, this would be overkill.
CodePudding user response:
but is there a way to do without that?
Yes, just add user-defined deduction guides for CTestDer
:
template<typename T>
CTestDer(T) -> CTestDer<T>;