模板参数推导和隐式类型转换
在 C 语言中,模板参数推导是一个强大的功能,可以根据模板参数的类型自动判断模板参数的类型。关于调用者的论点。但是,在推导过程中不会考虑某些类型的转换,包括用户定义的转换。
隐式转换问题
考虑以下代码片段:
<code class="cpp">template<typename Dtype> class Scalar{ Scalar(Dtype v) : value_(v){} private: Dtype value_; };</code>
Scalar 类表示简单的值类型。现在,考虑以下模板函数:
<code class="cpp">template<typename Dtype> void func(int a, Scalar<Dtype> b){ cout << "ok" <<endl; }
此函数接受一个 int 和一个 Scalar
在下面的 main 函数中,我们尝试使用 int 和 int 值调用 func:
<code class="cpp">int main(){ int a = 1; func(a, 2); // ERROR: template argument deduction fails return 0; }
但这会导致编译错误,指出模板论证推演失败。这是因为编译器无法自动将 int 值 2 转换为 Scalar
可能的解决方案
要修复对于此问题,您有多种选择:
调用方显式转换:
<code class="cpp">func(a, Scalar<int>(2));</code>
这会手动将 int 值转换为标量< ;int>;
推导指南:(仅限 C 17)
添加标量推导指南:
<code class="cpp">template<typename T> Scalar(T v) -> Scalar<T>;</code>
这告诉编译器在从调用者的参数推导 Scalar 类型时更喜欢这个推导指南,允许您将 func 调用为:
<code class="cpp">func(a, 2);</code>
显式实例化:
您可以显式实例化特定类型的 func:
<code class="cpp">func<int>(a, 2);</code>
这会强制编译器使用 Dtype = int 实例化函数,从而避免模板参数推导的需要。
以上是为什么 C 中的隐式类型转换导致模板参数推导失败?的详细内容。更多信息请关注PHP中文网其他相关文章!