如果类具有与类同名的成员,则生成构造函数

Posted

技术标签:

【中文标题】如果类具有与类同名的成员,则生成构造函数【英文标题】:Generated constructors if class has a member with same name as class 【发布时间】:2020-10-29 03:55:44 【问题描述】:

我有一个带有std::vector 成员的类,它与该类同名并且没有用户定义的构造函数;后来我有了一个生成这些对象之一的工厂方法:

#include <vector>

class data 
    std::vector<int> data;
;

data create()

    data d;
    // ...
    return d;

当我尝试使用 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 &&)'

在 Compiler Explorer 上,此代码在 MSVC 2019 上也失败了,但确实在 GCC 10.2 中编译。那么这是 MSVC 中的一个错误,是不是符合标准的代码,还是这种行为“依赖于实现”?

MSVC 和 GCC 都给出了明确的错误,即具有 user-declared 构造函数的类不能有同名的成员,但如果该类只有编译器生成的构造函数怎么办?那么将构造函数声明为defaultdelete 怎么样,这仍然算作用户声明的吗?

顺便说一句,我注意到如果我从std::vector 更改成员的类型,MSVC 的行为会有所不同,所以这个定义确实编译了:

class data 
    int data;
;

同样,如果工厂只是返回一个右值而不是本地值,MSVC 会再次编译它:

data create()  return ; 

【问题讨论】:

对我来说看起来像一个 MSVC 错误。相当奇怪的错误:p 【参考方案1】:

按照标准class.mem#21

如果类 T 具有用户声明的构造函数,则类 T 的每个非静态数据成员的名称都应与 T 不同。

所以你上面的代码是有效的,编译器必须接受它。错误报告:https://developercommunity.visualstudio.com/t/generated-constructors-if-class-has-a-member-with/1626621

将构造函数声明为defaultdelete 怎么样,这仍然算作用户声明的吗?

是的,这些也被视为用户声明的构造函数。

【讨论】:

以上是关于如果类具有与类同名的成员,则生成构造函数的主要内容,如果未能解决你的问题,请参考以下文章

Java构造函数

面向对象2

constructor和object的联系与对比

constructor&object 的联系与对比

构造函数的总结

constructor&object 的联系与对比