【发布时间】:2015-02-13 22:50:05
【问题描述】:
我希望在一些现有的 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;
}
- 如果 Clang 的编译标志设置为
-std=c++98和libstdc++,则没有问题,并且编译正常。 - 如果 Clang 的编译标志设置为
-std=c++11和libc++,我会收到错误No viable conversion from 'A' to 'value_type' (aka 'SerializableFormat')
只是为了说清楚——如果你正在考虑为类A 提供一个构造函数 SerializableFormat:
由于SerializableFormat 类更适合于各种类之间的转换,因此A(以及其他希望可序列化的类)拥有构造函数和转换运算符而不是期望SerializableFormat 是有意义的涵盖所有想要可序列化的类,因此修改SerializableFormat 使其具有特殊的构造函数不是解决方案。
谁能看到我在这里做错了什么?
【问题讨论】:
-
使用 GCC、libstdc++ 和
-std=c++11,它仍然可以编译。您的转换运算符返回const SerializableFormat没有意义——只需返回SerializableFormat,它也适用于clang——但我不知道您的代码是否有效。 -
直到刚才我才注意到 LLVM 标签。这改变了一切。
-
最小测试用例:
struct A { }; struct B { operator const A(); }; void f() { (A(B())); }在所有模式下都被 GCC 接受,仅在 C++03 模式下由 clang 接受。
标签: c++ c++11 llvm libstdc++ libc++