2011-08-24 54 views
1

假设我们有下面的代码:不止一个运营商,这些操作数相匹配

struct int64 
{ 
    long long value; 

    int64() : value(0) {} 
    int64(signed char i8) : value(i8) {} 
    int64(unsigned char u8) : value(u8) {} 
    int64(short i16) : value(i16) {} 
    int64(unsigned short u16) : value(u16) {} 
    int64(int i32) : value(i32) {} 
    int64(unsigned u32) : value(u32) {} 
    int64(long long i64) : value(i64) {} 
    int64(unsigned long long u64) : value(u64) {} 
    int64(const int64& i64) : value(i64.value) {} 

    int64& operator+=(const int64& rhs) { return value += rhs.value, *this; } 
    int64& operator-=(const int64& rhs) { return value -= rhs.value, *this; } 

    friend int64 operator+(const int64& lhs, const int64& rhs) { return int64(lhs) += rhs; } 
    friend int64 operator-(const int64& lhs, const int64& rhs) { return int64(lhs) -= rhs; } 

    operator char() const { return (char)value; } 
    operator short() const { return (short)value; } 
    operator int() const { return (int)value; } 
    operator long long() const { return value; } 
}; 

编译时的这段代码:发生

int64 q = 500; 
int64 m = q + 1024; 

错误有4类似的转换提供给1024和一个因对于q为整型,为了解决这个问题,我从int64中删除了operator XX,并添加了以下代码:

template <typename n> 
operator n() const { return (n)value; } 

现在我可以执行以下代码:

int64 q = 500; 
int64 m = q + 1024; 
short r = q; 

模板定义可与Visual C++GCC编译器,但Intel C++编译器。

我该如何编写适用于这些编译器的转换运算符?

回答

1

你应该写operator+定义为所有您支持的类型:

int64 operator+(int num) { 
    return int64(value + num); 
} 

int64 operator+(short num) { 
    ... 
} 

... 

你添加intint64和结果分配到int64,但它没有一个拷贝构造函数等等它将它转换为一些整型,并试图对所有这些转换运算符和构造函数做一些奇怪的事情。

+0

编译器生成的问题出了什么问题? –

+0

@你不会放弃生成的编译器(至少是copy ctor)吗? –

+0

如果您定义了任何其他构造函数,而不是复制函数或赋值运算符,则会放弃编译器生成的默认构造函数。 –

0

这里的问题在于,如果您既提供了内置类型的构造函数,又提供了同一类型的转换运算符,然后使用这两种类型的表达式,C++就无法真正地确定它应该采用哪种方式去。因此,“myInt64Variable + 1024”可能意味着“(int)myInt64Variable + 1024)”通过转换为int运算符或“myInt64Variable +(int64)1024”通过构造函数。

根据我的经验,处理此问题的最佳方法是不提供转换运算符,或者如果您必须拥有它们,则可以创建toInt()函数或类似函数。从自定义类型到内置类型的任何转换都将是有损的转换,否则为什么要使用自定义类型?并且在执行有损转换时让人们注意是一件好事。

0

与C++ 11(其中,当这个问题被问刚刚被批准)开始,你可以标记转换explicit

struct int64 
{ 
    // ... 

    explicit operator char() const { return (char)value; } 
    explicit operator short() const { return (short)value; } 
    explicit operator int() const { return (int)value; } 
    explicit operator long long() const { return value; } 
}; 

这应该在所有主要的编译器的最新版本的工作(我测试过的所有人都有足够的C++ 11支持)。然而

struct int64 
{ 
    // ... 

    template <typename n> 
    explicit operator n() const { return static_cast<n>(value); } 
}; 

,这意味着:您还可以,如果你想申请给你的模板转换操作符,虽然我更喜欢的四个非模板转换(加,这坠毁ICC的版本,我试了一下!)你不能做short r = q;。对我来说,这是一件好事,因为缩小转换真的应该是

short r = static_cast<short>(q); 
相关问题