假设我们有一个operator/自定义类:
struct my_class {
uint64_t value;
}
template<class T>
constexpr T operator/(const my_class& a, const my_class& b)
{
return static_cast<T>(a.value) / static_cast<T>(b.value);
}
Run Code Online (Sandbox Code Playgroud)
一个如何选择a / b(其中a和b是的my_class类型)返回int或double,例如?
您可以使用一些模板魔术和转换运算符.您可以先为表达式定义一个简单的包装器:
struct DivideMyClass {
DivideMyClass(const MyClass& lhs_, const MyClass& rhs_) : lhs{lhs_}, rhs_{rhs} {}
template<typename T>
operator T () const {
return static_cast<T>(lhs.value) / static_cast<T>(rhs.value);
}
private:
const MyClass& lhs;
const MyClass& rhs;
};
Run Code Online (Sandbox Code Playgroud)
然后,重载运算符可以这样做:
constexpr DivideMyClass operator/(const my_class& a, const my_class& b)
{
return DivideMyClass{a, b};
}
Run Code Online (Sandbox Code Playgroud)
然后你的代码将如下所示:
double d = MyClass{21} / MyClass{5}; // will be equal to 4.2
Run Code Online (Sandbox Code Playgroud)
该语言不会通过返回类型重载除法.你的代码会混淆其他思维,这是一个错误.如果你广泛使用这种方法,你最终会得到一个难以理解的代码.
另一件事,转换是隐含的,并没有任何说明是否真的在呼叫站点的运营商完成转换.
您将阻止AAA idom(几乎总是使用自动).auto可能会破坏你的代码,这是一件坏事.
像这样的技术应该用于模板表达和类似的东西.使用它进行简单的划分会使其他人感到困惑.