我有一个类,std::vector其中的成员与该类同名,并且没有用户定义的构造函数;后来我有一个工厂方法来生成这些对象之一:
#include <vector>
class data {
std::vector<int> data;
};
data create()
{
data d{};
// ...
return d;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用 Visual Studio 2017 (15.9.19) 构建它时,它无法编译:
error C2664: 'data::data(data &&)': cannot convert argument 1 from 'std::vector<int,std::allocator<int>>' to 'const data &'
note: Reason: cannot convert from 'std::vector<int,std::allocator<int>>' to 'const data'
note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
note: This diagnostic occurred in the compiler generated function 'data::data(data &&)'
Run Code Online (Sandbox Code Playgroud)
在 Compiler Explorer 上,此代码在 MSVC 2019 上也失败,但在 GCC 10.2 中编译。那么这是 MSVC 中的错误吗?它是不符合标准的代码,还是这种行为“依赖于实现”?
MSVC 和 GCC 都给出了明确的错误,即具有用户声明的构造函数的类不能具有同名的成员,但是如果该类只有编译器生成的构造函数怎么办?如果将构造函数声明为 或default,delete这仍然算作用户声明吗?
顺便说一句,我注意到如果我更改了成员的类型,MSVC 的行为会有所不同std::vector,因此这个定义确实可以编译:
class data {
int data;
};
Run Code Online (Sandbox Code Playgroud)
同样,如果工厂只是返回一个右值而不是本地值,MSVC 会再次编译它:
data create() { return {}; }
Run Code Online (Sandbox Code Playgroud)
根据标准class.mem#21
如果类 T 有一个用户声明的构造函数,则类 T 的每个非静态数据成员都应具有与 T 不同的名称。
所以你上面的代码是有效的,编译器必须接受它。此错误已在 Visual Studio 2022 版本 17.7 中修复:https://developercommunity.visualstudio.com/t/ generated-constructors-if-class-has-a-member-with/1626621
将构造函数声明为
defaultor 怎么样delete,这仍然算作用户声明吗?
是的,这些也被视为用户声明的构造函数。
| 归档时间: |
|
| 查看次数: |
104 次 |
| 最近记录: |