[英]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: gcc 7.1.1无法在上面的标记行编译:
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. f
可以转换为wrapper<int>
,所以我希望这会发生。 From there the compiler should be able to deduce that T
is int
. 从那里编译器应该能够推断出
T
是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
. 编译器可以正确推导出
std::pair
的模板参数,所以我想知道为什么wrapper
不是这种情况。
Any ideas? 有任何想法吗?
For class template argument deduction, the "overload set" is composed as described in [over.match.class.deduct/1] . 对于类模板参数推导,“重载集”的组成如[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) - 对于template-name指定的主类模板的每个构造函数,如果定义了模板,则具有以下属性的函数模板:
(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.1) - 模板参数是类模板的模板参数,后跟构造函数的模板参数(包括默认模板参数),如果有的话。
(1.1.2) - The types of the function parameters are those of the constructor.(1.1.2) - 函数参数的类型是构造函数的类型。
(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.1.3) - 返回类型是由模板名称和模板参数指定的类模板特化,对应于从类模板获得的模板参数。
(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.2) - 如果未定义主类模板C或未声明任何构造函数,则从假设构造函数C()中导出如上所述的附加函数模板。
(1.3) - An additional function template derived as above from a hypothetical constructor C(C), called the copy deduction candidate.
(1.3) - 如上所述从假设构造函数C(C)派生的附加函数模板,称为复制推导候选者。
(1.4) - For each deduction-guide, a function or function template with the following properties:
(1.4) - 对于每个演绎指南,具有以下属性的函数或函数模板:
(1.4.1) - The template parameters, if any, and function parameters are those of the deduction-guide.(1.4.1) - 模板参数(如果有)和函数参数是演绎指南的参数。
(1.4.2) - The return type is the simple-template-id of the deduction-guide.(1.4.2) - 返回类型是演绎指南的simple-template-id。
As you can see, the matching "function" in 1.1 only attempts to match the argument types to the template parameter types exactly . 如您所见,1.1中匹配的“函数”仅尝试将参数类型与模板参数类型完全匹配。 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. 它适用于
std::pair
的原因是由于项目1.3和它定义的“复制演绎候选”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.