简体   繁体   English

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

[英]C++ explicit integral user-defined conversion

I have a flags class witch is just a wrapper around an integer and I want to implement explicit conversion to to arbitrary integers types based on the conversion rules for the underlying integer type. 我有一个flags类,女巫只是一个整数的包装器,我想根据基础整数类型的转换规则将显式转换为任意整数类型。

ie

say I have the class along the lines of (ignoring non-relevant members) 说我有上课的方式(忽略无关的成员)

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

could I still convert to an integral type other than int say by 除了int说,我还能转换为整数吗?

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

rather than 而不是

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

or would I need to explicitly define a conversion operator for every integral type to be able to do this? 还是我需要为每种整数类型显式定义一个转换运算符才能做到这一点?

Note I'm using C++14 注意我正在使用C ++ 14

I've read http://en.cppreference.com/w/cpp/language/cast_operator but can't see any thing specific to integral types which makes me think I need to explicit define all valid conversion which I want to avoid. 我已经阅读了http://en.cppreference.com/w/cpp/language/cast_operator,但是看不到特定于整数类型的任何东西,这使我认为我需要显式定义所有想要避免的有效转换。 I would also be happy with a template conversion function which will fail if conversion to the target type isn't possible, noting I know the max value of the internal integer ie all flag bits turned on, as a macro/constant FLAGS_MAX , if this is of any use. 我也对模板转换函数感到满意,如果无法转换为目标类型,该函数将失败,请注意,我知道内部整数的最大值,即所有标志位均已打开,作为宏/常量FLAGS_MAX ,如果这样做有什么用。

could I still convert to an integral type other than int say by 除了int说,我还能转换为整数吗?

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

No, you can't. 不,你不能。

The above is equivalent to: 以上等同于:

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

The first line is wrong since flags cannot be implicitly converted to unsigned long long . 第一行是错误的,因为不能将flags隐式转换为unsigned long long

Given the definition of Flags , the only legal C++ method to initialize iflags is to use: 给定Flags的定义,初始化iflags的唯一合法C ++方法是使用:

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

If you remove the explicit qualifier from the conversion operator 如果从转换运算符中删除explicit限定词

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

then you can use 那么你可以使用

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

That static_cast attempt falls under [expr.static.cast]/4 , which roughly says that you can do static_cast<T>(e) if you can do T t(e); static_cast尝试属于[expr.static.cast] / 4 ,它粗略地说,如果可以执行T t(e);则可以执行static_cast<T>(e) T t(e); for some invented variable t (there's some fun dance in the wording to take care of guaranteed elision and C-style cast oddities, which we can ignore for our purposes). 对于某些发明的变量t (在措辞中有一些有趣的舞蹈,可以保证有保证的省略和C样式的转换奇数,我们可以忽略它们。)

That initialization is controlled by [dcl.init]/17.7 , which says you do overload resolution on the conversion functions of Flags , with a pointer to [over.match.conv] , which has this to say about candidates: 该初始化由[dcl.init] /17.7控制 ,它表示您对Flags的转换函数进行重载解析,并带有指向[over.match.conv]的指针,该指针对候选者有这样的说明:

Those non-explicit conversion functions that are not hidden within [ Flags ] and yield type [ unsigned long long ] or a type that can be converted to type [ unsigned long long ] via a standard conversion sequence are candidate functions. 那些未隐藏在[ Flags ]中并产生类型[ unsigned long long ]或可以通过标准转换序列转换为类型[ unsigned long long ]的类型的非显式转换函数是候选函数。 For direct-initialization, those explicit conversion functions that are not hidden within [ Flags ] and yield type [ unsigned long long ] or a type that can be converted to type [ unsigned long long ] with a qualification conversion are also candidate functions. 对于直接初始化,未隐藏在[ Flags ]中并产生类型[ unsigned long long ]的显式转换函数或可以通过限定转换转换为类型[ unsigned long long ]的类型也是候选函数。

Your explicit operator unsigned int() neither yields unsigned long long nor a type that can be converted to it via a qualification conversion (which is irrelevant here - that conversion only applies to pointer-y things); 您的explicit operator unsigned int()既不会产生unsigned long long也不会产生可通过限定转换将其转换为类型的类型(此处无关紧要-转换仅适用于指针y的事物); it is therefore not a candidate. 因此,它不是候选人。 Since the candidate set is empty, overload resolution fails, so the initialization is ill-formed, and so is the static_cast . 由于候选集为空,因此重载解析失败,因此初始化static_cast不正确, static_cast也是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM