Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ automatic template deduction fails for template argument

Tags:

c++

c++17

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;
}
like image 579
Jan Avatar asked Sep 24 '18 14:09

Jan


People also ask

What is template argument deduction?

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.

What is CTAD C++?

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.

Can we pass Nontype parameters to templates?

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.

CAN default arguments be used with the template?

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 { };


Video Answer


2 Answers

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.

like image 177
mister why Avatar answered Nov 14 '22 21:11

mister why


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.

like image 42
Jarod42 Avatar answered Nov 14 '22 20:11

Jarod42