我希望在一些现有的 c++ 项目中使用一些 c++11 特性,所以我开始在 Clang 中为一些项目更改编译标志,并且我一直遇到关于 C++11 处理转换运算符(或强制转换)的特定问题运算符),我没想到会看到并且不明白为什么当它是不是 c++11 的有效 C++ 代码时,为什么现在将其视为错误
我把它归结为这个简单的例子:
#include <iostream>
#include <vector>
class SerializableFormat
{
public:
size_t i;
};
class A
{
public:
size_t x, y;
A(size_t n) : x(n), y(1) { }
operator const SerializableFormat() const
{
SerializableFormat result;
result.i = x;
if (y)
{
result.i /= y;
}
return result;
}
};
int main(int argc, const char * argv[])
{
std::vector<SerializableFormat> v;
for(size_t i = 0; i < 20; i++)
{
v.push_back(A(i));
}
return 0;
}
-std=c++98
和 libstdc++
,则没有问题并且编译正常。 -std=c++11
和 libc++
,我会收到错误 No viable conversion from 'A' to 'value_type' (aka 'SerializableFormat')
0x214234只是为了说明清楚——如果您正在考虑为 SerializableFormat 提供一个仅用于
A
类的构造函数:由于
SerializableFormat
类更适合与各种类之间的转换,因此 A
(以及其他希望可序列化的类)具有构造函数和转换运算符是有意义的,而不是期望 SerializableFormat
覆盖所有类型的类可序列化,因此修改 SerializableFormat
以具有特殊的构造函数不是解决方案。谁能看到我在这里做错了什么?
最佳答案
正如注释正确指出的那样,您可以通过在 const
转换运算符的返回类型中删除 SerializableFormat
来进行编译:operator
const
SerializableFormat() const
至于 clang 这种行为是否正确,是有争议的。该问题正在由 clang bug report 16682 跟踪。目前有关于创建 CWG(C++ 委员会)问题报告的讨论,但尚未完成。我注意到这个错误报告已经开放了一段时间(2013-07-23),但最近在 2015-01-28 更新。
与此同时,实用的建议是永远不要返回 const
-value。这对于 C++98/03 来说是一个不错的建议,但是对于移动语义,它变成了糟糕的建议,因为它会禁用移动语义。
关于C++11 与 C++98 转换运算符的行为发生了变化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28510088/