【问题标题】:Emulating explicit cast in C++03在 C++03 中模拟显式转换
【发布时间】:2014-04-03 12:49:21
【问题描述】:

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

那么,是否可以在 C++03 中模拟显式转换?我显然知道显式布尔(或“安全”布尔)习语 - 但这仅用于转换为布尔类型。是否可以在 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 中模拟它(不使用自定义强制转换运算符)?

【问题讨论】:

  • “需要向后兼容 C++03 的遗留库”等什么?这个库使用的语言到底是什么?请记住,gcc 4.7.2 提供了 C++11 语言的不完整实现,并且 C++03 和 C++11 之间存在重大变化。
  • 我说的是使用#ifdefs,所以它可以用C++03和C++11编译
  • 这应该如何工作?编译器是否应该尝试它已知的每一对转换 Foo -&gt; XX -&gt;int

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


【解决方案1】:

“不完美的 C++”是对的,因为它使用了一个自定义的“关键字”——实际上是一个伪装成关键字的函数名(与 Tribool 的 indeterminate 不同)。如果您尝试static_cast,您将违反语言只能接受涉及最多一种用户定义类型的转换链的限制,而您有两种转换 - 从“Foo”到“int_cast”,然后从那里到@987654324 @。

如果你特别想能够static_cast,那么你可能不得不用宏破解一些东西来取代普通的static_cast...并接受生活在未定义的行为领域。我的首选实际上是 work in the inverse direction:在 C++11 模式下只需使用 explicit_cast 并使用宏将其重新定义为 static_cast 调用。我在我的 C++ 反向移植工具包中使用了显式转换,因此在我编写的所有 C++ 代码中,我没有发现任何重要问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 2013-01-23
    • 2011-04-05
    • 1970-01-01
    • 2013-06-17
    • 2016-06-03
    相关资源
    最近更新 更多