C++ has this helpful feature that says that the template parameter is implicit in the code inside a template class A.
However, for construction, this seems to clash with CTAD.
How can I make CTAD take precedence?
For example, here, there is an error in the f member because A is interpreted as A<T> where T is std::string, and not deduced from the parameter double.
#include<string>
template<class T>
struct A {
A(T const& t) {}
auto f() {return A{5.0};} // error here triggered by line 11 `auto a2 = a1.f();`
};
int main() {
A a1{std::string{"hello"}};
auto a2 = a1.f();
}
https://godbolt.org/z/3nc7nev3o
>Solution :
You need to use ::A to tell the compiler to use the name A from the global scope instead of using the name A in the class scope which is just shorthand for A<T>. That gives you:
#include<string>
template<class T>
struct A {
A(T const& t) {}
auto f() {return ::A{5.0};} // uses CTAD to return A<double>
};
int main() {
A a1{std::string{"hello"}};
auto a2 = a1.f();
}
as seen in this live example.
Another option is to add a private alias to the class type and then use that alias in the function as needed. That gives you:
#include<string>
template<class T>
struct A {
private:
template <typename U>
using NewA = A<U>;
public:
A(T const& t) {}
auto f() {return NewA{5.0};} // error here triggered by line 11 `auto a2 = a1.f();`
};
int main() {
A a1{std::string{"hello"}};
auto a2 = a1.f();
}
and can bee seen working here