我正在研究基于https://www.fluentcpp.com/category/strong-types/的包装类,主要区别在于,我正在用显式强制转换运算符替换get()
方法,因为这会在使用代码时触发问题。
如下面的简化代码所示,我有3个重载的Cast运算符:
const A &
到int
A &&
到int
const A &
到const int &
在编写static_cast<int>(a)
时,我希望使用const A &
到int
的重载。但是,似乎同样赞成int
和const int &
重载。 为什么这样做?
与此类似,它似乎允许const int &r = static_cast<const int &>(createA());
,我认为这是一生的错误。 (假设createA按值返回A)
Compiler Explorer中的简化代码:https://gcc.godbolt.org/z/YMH9Ed
#include <utility>
struct A
{
int v = 42;
explicit operator int() const & { return v; } // Removing this line works
explicit operator int() && { return std::move(v); }
explicit operator const int &() const & { return v; }
};
int main(int, char**)
{
A a;
int r = static_cast<int>(a);
return r;
}
编译错误:
<source>:14:13: error: ambiguous conversion for static_cast from 'A' to 'int'
int r = static_cast<int>(a);
^~~~~~~~~~~~~~~~~~~
<source>:6:14: note: candidate function
explicit operator int() const & { return v; }
^
<source>:8:14: note: candidate function
explicit operator const int &() const & { return v; }
^
答案 0 :(得分:3)
explicit operator int() const & { return v; }
和
explicit operator const int &() const & { return v; }
转换效果同样好。 a
是一个左值,因此可以调用两个函数。 a
也不是const
,因此这两个函数都必须将const转换应用于a
,因此它们仍然同样出色。剩下的就是“返回类型”,int
或const int&
,但是从它们创建int
都同样好。
您需要摆脱转换运算符之一,或删除常量 来自
explicit operator const int &() const & { return v; }
将其变成
explicit operator const int &() & { return v; }
因此非const左值会为您提供const引用。