【问题标题】:Defining your own explicit conversions定义自己的显式转换
【发布时间】:2011-11-07 06:37:18
【问题描述】:

假设,如果无法通过显式转换(例如static_cast)从一种类型转换另一种类型,是否可以为其定义显式转换运算符?

编辑

我正在寻找一种方法来为以下内容定义显式转换运算符:

class SmallInt {

public:

    // The Default Constructor
    SmallInt(int i = 0): val(i) {
        if (i < 0 || i > 255)
        throw std::out_of_range("Bad SmallInt initializer");
    }

    // Conversion Operator
    operator int() const {
        return val;
    }

private:
    std::size_t val;

};

int main()
{
     SmallInt si(100);

     int i = si; // here, I want an explicit conversion.
}

【问题讨论】:

  • 显式转换运算符将是返回目标类型的方法。还是我错过了什么?

标签: c++ type-conversion explicit


【解决方案1】:

在当前的标准中,从你的类型到不同类型的转换不能标记为explicit,这在一定程度上是有道理的:如果你想显式转换,你总是可以提供一个实现转换的函数:

struct small_int {
   int value();
};
small_int si(10);
int i = si.value();   // explicit in some sense, cannot be implicitly converted

再一次,它可能没有多大意义,因为在即将发布的标准中,如果您的编译器支持它,您可以将转换运算符标记为explicit

struct small_int {
   explicit operator int();
};
small_int si(10);
// int i = si;                 // error
int i = (int)si;               // ok: explicit conversion
int j = static_cast<int>(si);  // ok: explicit conversion

【讨论】:

    【解决方案2】:

    对于用户定义的类型,您可以定义type cast operator。运算符的语法是

    operator <return-type>()
    

    您还应该知道,隐式类型转换运算符通常不受欢迎,因为它们可能会给编译器留下太多余地并导致意外行为。相反,您应该在类中定义 to_someType() 成员函数来执行类型转换。


    对此不确定,但我相信 C++0x 允许您指定类型转换为 explicit 以防止隐式类型转换。

    【讨论】:

    • @Toolbox 哪些编译器实现了 C++11 的这个特性?我不认为 MSVC++ 2010 有。
    • @Seth Carnegie 根据gcc.gnu.org/projects/cxx0x.html,显式转换运算符在 GCC 4.5 中可用。我自己无法对此进行测试。
    【解决方案3】:

    如果这是你想要的,你可以定义转换运算符,例如:

    void foo (bool b) {}
    
    struct S {
       operator bool () {return true;} // convert to a bool
    };
    
    int main () {
       S s;
       foo (s);  // call the operator bool.
    }
    

    虽然不是真的推荐,因为一旦定义,这种隐式转换可能会发生在你意想不到的尴尬地方。

    【讨论】:

    • 是的,但是我可以把它变成只接受显式转换吗?
    • 我认为在 C++0x 中是这样,正如上面的答案所说。为什么不直接定义一个to_XXX 成员函数?
    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多