【发布时间】:2018-12-17 09:56:06
【问题描述】:
我创建了一个模板结构,并试图重载二元运算符。由于某种原因,即使类型在两者之间正确转换,该函数也不会返回正确的数据类型。
template<typename T>
struct Number{
const T value;
Number(T a) : value(a) {}
template<typename U>
auto operator*(Number<U> other){
auto new_value = value*other.value;
std::cout << typeid(new_value).name() << std::endl;
return Number(new_value);
}
};
现在,如果我使用 main 中调用的以下代码执行此操作。它返回第一个类型的编号,而不是更高类型的编号。
auto b = Number<int>(6) * Number<double>(2.3); // this should be an int*double=double
std::cout << b.value << typeid(b.value).name() << std::endl;
auto c = Number<double>(2.3) * Number<int>(6);
std::cout << c.value << typeid(c.value).name() << std::endl;
输出如下: d 13i d 13.8天
据我了解,当函数返回新的Number(new_value) 时,调用了不正确的构造函数。我不明白为什么会发生这种情况,因为 new_value 是“正确的类型”。
【问题讨论】:
-
您是否希望在此处进行类模板参数推导?我认为您只是在使用注入的类名。
-
我期待调用 T=double 的 Number 构造函数。啊,我明白了。你的意思是因为代码在模板中,所以它立即使用 T 直到它“离开”结构?
-
@Helv 没错。
-
也许这里有一个教训:CTAD 为语言增添了魔力。魔术在起作用时很棒,而在不起作用时则完全神秘。因此,如果您的代码对人类读者来说易于理解很重要,那么您可能希望谨慎使用魔法,并充分考虑权衡取舍。存在一个无聊的、非魔法的解决方案,可以使用它来代替。
-
请正确缩进您的代码