Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force class template argument deduction when constructing a class in its own member functions?

Tags:

c++

c++17

Consider following code:

struct A {};

template <typename T> struct B
{
    B(T) {}
    auto foo() {return B(A{});} // error: no matching function for call to 'B<int>::B(A)'
};

auto foo() {return B(A{});} // compiles

int main()
{
    foo();
    B b(0);
    b.foo();
}

Try it live

I understand why B::foo() doesn't compile: Inside of struct B<T>, B (as an injected-class-name) means B<T> unless it's explicitly used as a template. Which in this case prevents class template argument deduction.

Let's say I can't do auto foo() {return B<A>(A{});} since my actual code relies on slightly elaborate user-provided deduction guides.

The question is: How do I force class template argument deduction when constructing B inside of B::foo?

I hope I'm not missing something obvious.

like image 521
HolyBlackCat Avatar asked Aug 08 '18 19:08

HolyBlackCat


2 Answers

You qualify it so that it's not the injected-class-name.

auto foo() {return ::B(A{});}
like image 101
T.C. Avatar answered Sep 19 '22 11:09

T.C.


Another option is to use a function to do the type deduction for you.

template <typename T> B<T> make_b(T t) { return B<T>(t); }

and use

auto foo() {return make_b(A{});} 
like image 38
R Sahu Avatar answered Sep 23 '22 11:09

R Sahu