Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't the compiler deduce the template parameter when used with a conversion operator?

Consider the following code:

#include <utility>

template<typename T>
struct wrapper {
    T value;
};

struct foo {
    operator wrapper<int>() {
        return{10};
    }
};


int main() {
    foo f;
    wrapper w = f; // error
    std::pair p = std::make_pair(1, 0); // ok
}

gcc 7.1.1 fails to compile at the marked line above:

main.cpp: In function 'int main()':
main.cpp:17:17: error: class template argument deduction failed:
     wrapper w = f; // error
                 ^
main.cpp:17:17: error: no matching function for call to 'wrapper(foo&)'
main.cpp:4:8: note: candidate: template<class T> wrapper(wrapper<T>)-> wrapper<T>
 struct wrapper {
        ^~~~~~~
main.cpp:4:8: note:   template argument deduction/substitution failed:
main.cpp:17:17: note:   'foo' is not derived from 'wrapper<T>'
     wrapper w = f; // error
                 ^

f is convertible to wrapper<int>, so I expect that to happen. From there the compiler should be able to deduce that T is int. But it can't.

The compiler can deduce std::pair's template parameter correctly, so I'm wondering why this isn't the case with the wrapper.

Any ideas?

like image 615
Rakete1111 Avatar asked Jun 18 '17 06:06

Rakete1111


People also ask

Why do we use template template parameter?

Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.

Can we pass Nontype parameters to templates?

Template non-type arguments in C++It is also possible to use non-type arguments (basic/derived data types) i.e., in addition to the type argument T, it can also use other arguments such as strings, function names, constant expressions, and built-in data types.

Can a template parameter be a function?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Can a template be a template parameter?

Templates can be template parameters. In this case, they are called template parameters. The container adaptors std::stack, std::queue, and std::priority_queue use per default a std::deque to hold their arguments, but you can use a different container.


1 Answers

For class template argument deduction, the "overload set" is composed as described in [over.match.class.deduct/1]. Those are the following:

A set of functions and function templates is formed comprising:
(1.1) - For each constructor of the primary class template designated by the template-name, if the template is defined, a function template with the following properties:
(1.1.1) - The template parameters are the template parameters of the class template followed by the template parameters (including default template arguments) of the constructor, if any.
(1.1.2) - The types of the function parameters are those of the constructor.
(1.1.3) - The return type is the class template specialization designated by the template-name and template arguments corresponding to the template parameters obtained from the class template.

(1.2) - If the primary class template C is not defined or does not declare any constructors, an additional function template derived as above from a hypothetical constructor C().

(1.3) - An additional function template derived as above from a hypothetical constructor C(C), called the copy deduction candidate.

(1.4) - For each deduction-guide, a function or function template with the following properties:
(1.4.1) - The template parameters, if any, and function parameters are those of the deduction-guide.
(1.4.2) - The return type is the simple-template-id of the deduction-guide.

As you can see, the matching "function" in 1.1 only attempts to match the argument types to the template parameter types exactly. It doesn't take conversion into account (much like most other template deduction related behavior).

The reason it works for std::pair is due to item 1.3, and the "copy deduction candidate" it defines.

like image 96
StoryTeller - Unslander Monica Avatar answered Oct 08 '22 00:10

StoryTeller - Unslander Monica