简体   繁体   English

为什么编译器在与转换运算符一起使用时不能推导出模板参数?

[英]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 . 从那里编译器应该能够推断出Tint 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.

相关问题 为什么编译器不能从返回类型中推导出模板参数? - Why can't the compiler deduce template parameter from return type? 使用辅助模板结构时无法推断模板参数 - Can't deduce template parameter when helper template struct is used 为什么 GCC 编译器不能以别名模板形式从 std::array 推导出模板参数之一 - Why can't GCC compiler deduce one of the template parameter from std::array in alias template form 编译器无法推论非成员operator +的模板参数 - compiler can't deduce template parameters of nonmember operator+ 为什么在零数组的情况下编译器不推导template参数? - Why a compiler doesn't deduce the template parameter in case of zero array? 编译器无法推断基本功能中的模板参数 - Compiler can't deduce template parameter in basic function 为什么编译器不能推导出自动模板参数,除非我添加const? - Why can't the compiler deduce auto template parameter unless I add const? 如果参数类型取决于模板参数,为什么编译器不能推断返回类型 - Why can't the compiler deduce the return type if argument type depends on a template parameter 为什么编译器不能推导出这个简单函数的模板参数? - Why can't the compiler deduce template argument for this simple function? 为什么编译器不能从默认参数推导出模板类型? - Why can't the compiler deduce the template type from default arguments?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM