c++中按引用传递和按值传递之间重载歧义的实用解决方案
Practial solution to overload ambiguity between pass by reference and pass by value in C++
我有一个3d矢量类的类模板,看起来有点像(缩写):
template<typename T>
class vector3
{
public:
typedef vector3<T> self;
self& operator*(T& a);
self& operator*(T a);
T x,y,z;
};
两个操作符*都重载向量与标量的"自乘法",并返回*this。
我希望能够像这样使用类模板:
vector3<double> vv;
double scalar;
vv*scalar;
vv*0.5;
重载歧义是明确的,"让它工作"的解决方案是可用的,并且已经在其他SA问题中讨论过。
如果删除操作符*(T&A),一切都可以编译,但你(至少在理论上),失去了一些性能优势传递值当你真的不需要(对吗?)
如果去掉操作符*(ta),就不能做vv*0.5。
如果你重命名其中的一个,在所有这些操作直观上有意义的情况下,你会失去很多代码的清晰度。
是否有任何方法在有意义的情况下保留引用传递,但消除重载歧义?确保vector3模板容纳上述两个表达式的最佳方法是什么?
你最好的选择是
self operator * (const T& a) const;
有三个时刻:
用
const T&
代替T
或T&
。现代编译器很聪明,它们会优化代码,并通过值而不是引用传递小类型。操作符
*
不能改变操作数操作符
*
应该返回一个值而不是一个引用
让另一个取右值引用:
self operator*(T& a); // for 'scalar'
self operator*(T&& a); // for 0.5
虽然,你真的有一个不同的operator*
实现两种不同的情况?你可能只需要:
template <typename U,
typename = std::enable_if_t<std::is_same<std::decay_t<U>, T>::value>>
self operator*(U&& a); // for both
注意operator*
应该返回一个值。operator*=
应该返回一个引用。
您可以像Barry描述的那样创建一个以右值为参数的方法。
或者你的模板参数可以是const
,如果实现没有修改它。在这种情况下,您只能有一个方法接受const
引用:
self operator*(const T& a) const;
相关文章:
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- 在一个解决方案中针对第三方静态库 (Creo) 的不同版本(版本)进行构建
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- N-queen问题:无法弄清楚为什么我的解决方案不起作用
- 从排序数组中删除重复项,具有不同代码方式的相同解决方案具有不同的输出
- 为什么这种ADL解决方案歧义
- c++中按引用传递和按值传递之间重载歧义的实用解决方案