c++ - 使用可隐式转换为模板类对象的参数调用函数

标签 c++ templates compiler-errors

考虑以下示例 ( godbolt ):

template <typename T>
struct S {
    S(int) {}
};

template <typename T>
void f(S<T>, T) {}

int main() {
    f(1, 2);
}

编译出现如下错误:

<source>: In function 'int main()':
10 : <source>:10:11: error: no matching function for call to 'f(int, int)'
     f(1, 2);
           ^
7 : <source>:7:6: note: candidate: template<class T> void f(S<T>, T)
 void f(S<T>, T) {}
      ^
7 : <source>:7:6: note:   template argument deduction/substitution failed:
10 : <source>:10:11: note:   mismatched types 'S<T>' and 'int'
     f(1, 2);
           ^

制作S非模板使示例编译。

为什么尽管从 int 进行了隐式转换,但此代码仍无法编译?至 S<T>

最佳答案

模板函数不是函数。它们是编写函数的模板。

template <typename T>
void f(S<T>, T) {}

这是一个模板,用于编写给定类型 T 的函数.

现在,C++ 在某些情况下会尝试推导 T为你。它所做的是对每个参数进行模式匹配(一次)。

如果任何参数找不到匹配项,或者推导的类型不一致或不完整,则推导失败。不尝试转换或部分匹配。如果找到匹配项,它们将作为候选者添加到正在考虑的重载中(这里有一些规则),然后重载解析开始。

在重载决议时间转换被考虑。在模板类型推导中,它不是除了转换为基础。

在你的例子中,S<T>无法推断类型 T来自 1 .所以推论根本失败了。在考虑转换的情况下,我们永远不会达到过载解决方案。

碰巧你可以在演绎过程中阻止一个论点被考虑:

template<class T>struct tag_t{using type=T;}:
template<class T>using block_deduction=typename tag_t<T>::type;

template <typename T>
void f(block_deduction<S<T>>, T) {}

现在你的主要编译。

关于c++ - 使用可隐式转换为模板类对象的参数调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46187748/

相关文章:

java - 如何在另一个类的一个类中调用方法?

c++ - 我可以在哪里获得在 Linux 上对 C++ 代码运行 Sonar 库代码分析的步骤

c++ - QT Framework 从 4.7.2 更新到 5.2.1,QT 不想配置并给出 fatal error

c++ - 在编译时确定指针类型

c++ - 当函数接受 T&& 的参数并传递左值时,模板参数 T 是否应该解析为 T&?

C++ : How to make a specific binary (executable) for each trait?

c++ - 单元测试并发代码

c++ - 如何用 C 在 pcre 中编写适当的模式

Java:找不到符号(构造函数)

c - _Static_assert 替换以在 C 中显示值