I would like to better understand why automatic template deduction (applied when compiled with g++ -std=c++17
) works in the first three lines in main()
, but fails in the fourth. Is there any chance it will be accepted by compilers in the near future?
template <typename P = void>
class A {
public:
void f1() {}
};
template<typename C>
void g() {}
int main() {
A<> a; // works
A aa; // works
g<A<>>(); // works
g<A>(); // fails
return 0;
}
Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template.
Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.
Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.
You cannot give default arguments to the same template parameters in different declarations in the same scope. The compiler will not allow the following example: template<class T = char> class X; template<class T = char> class X { };
It's just a matter of signature. Basically you're passing the wrong type.
Both A a
and A<> a
mean you want an instance of A
with the default template parameter value, that is, you end up with A< void >
.
The function g< C >()
accepts a template parameter which happens to be a type, not another templated type. When you invoke it with A<>
, you tell the compiler that you want to use "the instantiation" of the templated type A
, which is valid. When you invoke it with A
you tell the compiler you want to invoke g< C >()
with C
being a templated type which does not fit its signature.
If you declare/define g()
like so template <typename <typename> TTemplatedType> g()
it will accepts to be invoked like this g< A >()
but g< A<> >()
will fail because now it no longer wants something else than a templated type.
With C++17, template argument deduction is also performed when the name of a class template is used as the type of an object being constructed.
Nothing changes for explicit type inside template.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With