C++11 与 C++98 转换运算符行为发生变化?
C++11 vs C++98 conversion operator behavior changes?
我希望在一些现有的 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')
只是为了说清楚——以防您正在考虑为 SerializableFormat 提供一个仅用于 class A
:
的构造函数
由于 SerializableFormat
class 更适合与各种 class 进行相互转换,因此对于 A
(以及其他 class希望序列化的 es) 拥有构造函数和转换运算符,而不是期望 SerializableFormat
涵盖想要序列化的每种类型的 class,因此修改 SerializableFormat
以具有特殊的构造函数是不是解决方案。
谁能看出我做错了什么?
正如评论正确指出的那样,您可以通过在 SerializableFormat
转换运算符的 return 类型中删除 const
来进行编译:
operator
const
SerializableFormat() const
至于clang这种行为是否正确,是有争议的。 clang bug report 16682 正在跟踪此问题。目前正在谈论创建 CWG(C++ 委员会)问题报告,但尚未完成。我注意到此错误报告已经开放了一段时间 (2013-07-23),但最近更新于 2015-01-28。
同时,切合实际的建议是永远不要将 return 提高 const
值。这对 C++98/03 来说是个不错的建议,但是移动语义变成了糟糕的建议,因为它会禁用移动语义。
我希望在一些现有的 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')
只是为了说清楚——以防您正在考虑为 SerializableFormat 提供一个仅用于 class A
:
由于 SerializableFormat
class 更适合与各种 class 进行相互转换,因此对于 A
(以及其他 class希望序列化的 es) 拥有构造函数和转换运算符,而不是期望 SerializableFormat
涵盖想要序列化的每种类型的 class,因此修改 SerializableFormat
以具有特殊的构造函数是不是解决方案。
谁能看出我做错了什么?
正如评论正确指出的那样,您可以通过在 SerializableFormat
转换运算符的 return 类型中删除 const
来进行编译:
operator
const
SerializableFormat() const
至于clang这种行为是否正确,是有争议的。 clang bug report 16682 正在跟踪此问题。目前正在谈论创建 CWG(C++ 委员会)问题报告,但尚未完成。我注意到此错误报告已经开放了一段时间 (2013-07-23),但最近更新于 2015-01-28。
同时,切合实际的建议是永远不要将 return 提高 const
值。这对 C++98/03 来说是个不错的建议,但是移动语义变成了糟糕的建议,因为它会禁用移动语义。