C++显式积分用户定义转换

C++ explicit integral user-defined conversion

本文关键字:用户 定义 转换 C++      更新时间:2023-10-16

我有一个flags类,它只是一个整数的包装器,我想根据底层整数类型的转换规则实现到任意整数类型的显式转换。

说我的课是按照的思路(忽略非相关成员)

class Flags {
unsigned int v;
explicit operator unsigned int() { return v; }
}

我还能转换成int以外的整数类型吗?比如

unsigned long long iflags = static_cast<unsigned long long>(flags);

而不是

unsigned long long iflags = static_cast<unsigned int>(flags);

或者我需要为每个积分类型明确定义一个转换运算符才能做到这一点?

注意:我使用的是C++14

我读过http://en.cppreference.com/w/cpp/language/cast_operator但是看不到任何特定于积分类型的东西,这让我认为我需要显式定义我想要避免的所有有效转换。我也很乐意使用模板转换函数,如果无法转换为目标类型,该函数将失败,请注意,如果有任何用处,我知道内部整数的最大值,即所有标志位都打开,作为宏/常量FLAGS_MAX

static_cast的尝试属于[expr.static.cast]/4,大致上说,如果你能为一些发明的变量tT t(e);,你就可以做static_cast<T>(e)(在措辞中有一些有趣的舞蹈来处理保证省略和C风格的强制转换,我们可以忽略这些)。

该初始化由[dcl.init]/17.7控制,它表示您对Flags的转换函数进行过载解析,并将指针指向[over.match.conv],这对候选者来说是这样的:

那些不隐藏在[Flags]和屈服类型[unsigned long long],或者可以是通过标准转换转换为类型[unsigned long long]序列是候选函数。对于直接初始化未隐藏在[Flags]中的显式转换函数,以及yield类型[unsigned long long]或可以转换为具有限定转换的类型[unsigned long long]也是候选函数。

您的explicit operator unsigned int()既不产生unsigned long long,也不产生可以通过限定转换转换为它的类型(这在这里无关紧要——该转换仅适用于指针式事物);因此,它不是候选人。由于候选集为空,过载解析失败,因此初始化不正确,static_cast也是如此。

我还能通过转换为int以外的整数类型吗

unsigned long long iflags = static_cast<unsigned long long>(flags);

不,你不能。

以上相当于:

unsigned long long temp(flags);
unsigned long long iflags = temp;

第一行是错误的,因为flags不能隐式转换为unsigned long long

给定Flags的定义,初始化iflags的唯一合法C++方法是使用:

unsigned long long iflags = static_cast<unsigned int>(flags);

如果从转换运算符中删除explicit限定符

class Flags {
unsigned int v;
public:
operator unsigned int() { return v; }
}

然后你可以使用

unsigned long long iflags = static_cast<unsigned long long>(flags);