Home > front end >  C - Deducing type from inherited constructor's arguments for class template
C - Deducing type from inherited constructor's arguments for class template

Time:01-31

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:

  1. Use a variadic template in the deduction guide
  2. Have the deduction guide use decltype to construct, using its own deduction guide, the superclass
  3. Use a specialization to figure out the superclass's template parameters
  4. 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>;

Demo

  •  Tags:  
  • Related