gpt4 book ai didi

c++ - 模板类的二元运算符不解决隐式转换

转载 作者:行者123 更新时间:2023-11-30 03:16:32 26 4
gpt4 key购买 nike

考虑以下类,其中第一个是模板化的。两者都是为了保存一个数值。

template<typename T>
struct foo
{
foo(T val) : val{ val } {}
T val;
};

struct bar
{
bar(double val) : val{ val } {}
double val;
};

我想定义一种方法来将这些类添加到一起以获得具有不同值的新类。

template<typename T>
foo<T> operator+(foo<T> a, foo<T> b)
{
return foo<T>(a.val + b.val);
}

bar operator+(bar a, bar b)
{
return bar(a.val + b.val);
}

当我将这些运算符用于隐式转换时,运算符使用 foo 类型的对象不使用 double 值的隐式转换来应用我的重载运算符,即使它可以为非模板类​​执行此操作。结果是没有与该表达式中的类型匹配的运算符。

int main()
{
foo<double> foo_value(11.0);
bar bar_value(11.0);

foo<double> ev1 = foo_value + 1.0; // no operator matches these operands
bar ev2 = bar_value + 1.0;
}

运算符是否必须首先显式实例化?如果是这样,a) 那看起来如何,以及 b) 如果在初始化 foo<double> 类型的对象时可以完成实例化,为什么不隐式完成实例化? ?

如果标准不支持任何类型的分辨率而不显式转换 1.0foo<double> 类型的值,我认为唯一的另一种可能性是为我想使用的每种类型定义运算符重载(对于 lhs 和 rhs)?

最佳答案

关于模板,您必须记住的一点是它们不会为您进行转换。他们所做的就是尝试弄清楚事物的类型,如果它与模板参数相符,那么它将淘汰该函数并调用它。

在你这样做的情况下

foo_value + 1.0

编译器运行正常,让我们看看有没有 operator +这将适用于此。它发现

template<typename T>
foo<T> operator+(foo<T> a, foo<T> b)
{
return foo<T>(a.val + b.val);
}

然后它试图找出什么 T是这样它可以消除一个具体的功能。它看着 foo_value , 看到它是一个 foo<double>所以它说第一个参数T需要是 double .然后它查看1.0一切顺利,我有一个 double那就是你遇到问题的时候。编译器无法推断出什么 T应该是 b因为它需要一个 foo<some_type> , 但得到一个 double反而。因为它无法推断类型,所以您的代码无法编译。

为了获得您想要的行为,您需要添加

template<typename T>
foo<T> operator+(foo<T> a, T b)
{
return foo<T>(a.val + b);
}

它可以让你添加 Tfoo<T> , 或者更好

template<typename T, typename U>
foo<T> operator+(foo<T> a, U b)
{
return foo<T>(a.val + b);
}

它可以让你添加任何东西到 foo<T> (例如 foo<double> + int 第一个版本不允许这样做)

关于c++ - 模板类的二元运算符不解决隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56262451/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com