在C ++ 03中模拟显式强制转换
我正在研究一个遗留库,它需要向后兼容C ++ 03,但是它也是向前兼容的,以利用移动语义和显式强制转换等C ++ 11功能。
那么,是否有可能在C ++ 03中模拟显式转换? 我明显知道显式布尔(或“安全”布尔)成语 - 但这只是为了转换为布尔类型。 是否有可能在C ++ 03中模拟一个普通的显式操作符?
我检查了一下,并在一本名为“不完美的C ++:实际编程的实用解决方案”的书中找到了关于此的讨论。
在本书中,他们讨论了关于在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 ++”是正确的,因为它使用了一个自定义的“关键字” - 实际上是一个伪装成关键字的函数名(例如:Tribool的indeterminate
)。 如果您尝试使用static_cast
则会碰到语言只能接受涉及多达一种用户定义类型的转换链的限制,而您有两次转换 - 从“Foo”到“int_cast”并从那里转换为int
。
如果你想特别地能够static_cast
那么你可能不得不用宏来破解一些东西来取代普通的static_cast
...并且接受生活在Undefined Behavior Land中。 我的首选是反向工作:只需使用explicit_cast
并在C ++ 11模式下使用一个宏将其重新定义为static_cast
调用。 我在C ++ backports工具包中使用显式强制转换,因此在我编写的所有C ++代码中使用了显式强制转换,到目前为止我还没有发现任何重要的问题。
上一篇: Emulating explicit cast in C++03
下一篇: ptr as class member and move semantics fail to compile with clang