Deduce template parameter of class member from constructor of class

414 Views Asked by At

I have a class A which contains a templated member B whose exact type should be deduced from A's constructor. The way this is supposed to work is that, as shown in the below example, B can be instantiated with either 1 or 2 parameters to its constructor (deduction guide will tell) but will take a const char* in any case. When I instantiate A with the const char* argument for the constructor, an object B should be instantiated from the const char* as A only takes a B object. However, this is how far I get:

#include <iostream>

template <bool LengthOpt>
struct B
{
    B(const char*) { }

    B(const char*, size_t) {  }

    void print() {
        if constexpr (LengthOpt) {
            std::cout << "LengthOpt is set" << std::endl;
        }
    }
};

B(const char*) -> B<false>;
B(const char*, size_t) -> B<true>;


template <template <bool LengthOpt> class T>
struct A
{
    A(T is) : is_{is} {
        
    }

    void print() {
        is_.print();
    }

    T is_;
};

int main()
{
    A a("hello");

    a.print();
}

And it yields those errors:

<source>:24:7: error: use of template template parameter 'T' requires template arguments; argument deduction not allowed in function prototype
    A(T is) : is_{is} {
      ^
<source>:21:43: note: template is declared here
template <template <bool LengthOpt> class T>
                                          ^
<source>:32:5: error: use of template template parameter 'T' requires template arguments; argument deduction not allowed in non-static struct member
    T is_;
    ^
<source>:21:43: note: template is declared here
template <template <bool LengthOpt> class T>
                                          ^
<source>:37:7: error: no viable constructor or deduction guide for deduction of template arguments of 'A'
    A a("hello");
      ^
<source>:22:8: note: candidate template ignored: could not match 'A<T>' against 'const char *'
struct A
       ^
<source>:22:8: note: candidate function template not viable: requires 0 arguments, but 1 was provided

My take on the problem is that the compiler doesn't know that I want to instantiate an object B in A's constructor, as the template template argument specifies nothing. It could very well be just any object that takes one template parameter.

I'm scratching my head right now on how to resolve this. Is it even possible or am I scratching a limitation in C++ again?

0

There are 0 best solutions below