在C ++ 03中模拟显式强制转换

时间:2014-03-02 16:43:56

标签: c++ c++11 c++03

我正在研究一个需要向后兼容C ++ 03的遗留库,但也可以向前兼容以利用C ++ 11的特性,如移动语义和显式转换。

那么,是否有可能在C ++ 03中模拟显式转换?我明显知道明确的bool(或“安全”bool)习语 - 但这只是用于转换为布尔类型。是否可以在C ++ 03中模拟一般的显式强制转换操作符?

我查了一下,并在一本名为“Imperfect C++ : Practical Solutions for Real-Life Programming”的书中找到了对此的讨论。

在本书中,他们讨论了在C ++ 03中模拟显式转换的一些想法(这本书是在C ++ 11之前编写的)。最终,他们建议您创建一个explicit_cast<T>模板。但是,我不喜欢这个解决方案,因为我希望用户能够使用static_cast<T>,这在C ++ 11中运行良好。

因此,另一种解决方案是强制编译器执行两次转换,这将禁止隐式转换。一个例子就是:

class int_cast
{
    public:

    int_cast(const int& v) : m_value(v)
    { }

    operator int() const
    {
        return m_value;
    }

    private:

    int m_value;
};

struct Foo
{
    Foo()
    {
        x = 10;
    }

    operator int_cast() const
    {
        return int_cast(x);
    }

    int x;
};

此处,Foo显式可转换为int,但不能隐式。 (此代码几乎逐字逐句地从 Imperfect C ++ 中解除,除了在他们的示例中他们将自定义Time对象转换为std::tm

然而,这实际上并不起作用,至少不使用GCC 4.7.2:

Foo f;
int x = static_cast<int>(f);

这导致:

test3.cpp: In function ‘int main()’:
test3.cpp:44:28: error: invalid static_cast from type ‘Foo’ to type ‘int’

所以我猜“不完美的C ++”在这里是错误的。即使使用显式强制转换,编译器也无法将Foo转换为int。 (也许这适用于较旧的编译器?)那么,无论如何都要在C ++ 03中模拟它(不使用自定义强制转换操作符)?

1 个答案:

答案 0 :(得分:3)

“不完美的C ++”是对的,因为它使用自定义的“关键字” - 实际上是伪装成关键字的函数名称(不像例如:Tribool的indeterminate)。如果你尝试static_cast,你会遇到限制,即语言只接受涉及多达一个用户定义类型的转换链,而你有两个转换 - 从“Foo”到“int_cast”,从那里到int

如果你想特别能够static_cast,那么你可能不得不用宏来破解正常static_cast ...并接受生活在未定义的行为领域。我的首选是实际work in the inverse direction:在C ++ 11模式下,只需使用explicit_cast并使用宏将其重新定义为static_cast调用。我在我的C ++ backports工具包中使用显式强制转换,因此在我编写的所有C ++代码中都使用了,我到目前为止找不到重要的问题。