C++ 隐式声明(对象级)成员函数如何根据isoc++;11标准?

C++ 隐式声明(对象级)成员函数如何根据isoc++;11标准?,c++,c++11,C++,C++11,这些类定义等效吗 第一个定义: class A { std::string s; }; class A { std::string s; public: A() : s() { } ~A(){ } A(const A& AA) : s(AA.s) { } A(A&& a) noexcept : s(std::move(a.s)) { } A& operator=(const A& AA){

这些类定义等效吗

第一个定义:

class A
{
    std::string s;
};
class A
{
    std::string s;
public:
    A() : s() {  }
    ~A(){  }
    A(const A& AA) : s(AA.s) {  }
    A(A&& a) noexcept : s(std::move(a.s)) {  }
    A& operator=(const A& AA){
        s=AA.s;
        return *this;
    }
    A& operator=(A&& a) noexcept{
        s=(std::move(a.s));
        return *this;
    }
    const A* operator&() const{ return this; }
    A* operator&(){ return this; }
};
第二个定义:

class A
{
    std::string s;
};
class A
{
    std::string s;
public:
    A() : s() {  }
    ~A(){  }
    A(const A& AA) : s(AA.s) {  }
    A(A&& a) noexcept : s(std::move(a.s)) {  }
    A& operator=(const A& AA){
        s=AA.s;
        return *this;
    }
    A& operator=(A&& a) noexcept{
        s=(std::move(a.s));
        return *this;
    }
    const A* operator&() const{ return this; }
    A* operator&(){ return this; }
};

如果不是,您能给我看一个与第一个类定义等效的类定义,并显式定义类a的所有成员函数吗?

这取决于您对“等效”的定义

  • 代码gen的汇编输出,对于一个好的编译器和优化器,它们应该是::-)
  • 编译器在生成AST和生成类表示或中间代码时的假设,为什么
。。。从(我相信它与主要标准没有太大区别)

为了让事情变得简单,对于特殊的成员函数,以默认构造函数为例,我们从这一节中看到:(重点是我的)

12.1.5:。。。。在隐式定义类的默认构造函数之前,所有非用户提供的默认构造函数 对于其基类和非静态数据成员 隐式定义的。[注:隐式声明的默认值] 构造函数具有异常规范。显式默认 定义可能有一个隐含的异常规范,见8.4。 -[完注]

上述内容并不完全适用于您的代码,尽管如此,进一步的支持证据仍然存在

12.6.3:非显式复制/移动构造函数是转换构造函数。隐式声明的复制/移动构造函数不是显式构造函数;可以为隐式类型转换调用它

检查一下你自己,有更多的支持证据。。。因此,在标准的意义上,一旦明确定义了任何特殊的成员函数,它就不同于编译器所创建的函数及其相关的假设

但在一天结束时,代码生成器可能会生成相同的代码。:-。只是编译过程中编译器的假设可能不同

TLDR


标准(草案)中还有许多其他段落,其中对隐式定义的特殊成员函数的效果及其相反的效果进行了区分(大部分没有提及)。您可以选择标准并搜索短语“隐式定义”的所有匹配项

它们当然是不同的;第二个函数在其默认构造函数中以不同的方式初始化
s
。@MadameElyse:我猜这只是OP的一个输入错误。丹尼尔,请澄清一下。。。另外,,“As”对于类名来说是一个相当糟糕的选择,它非常令人困惑。即使是MWE;改为使用“A”。
string(“”
vs
string()
-一个不是默认构造函数
运算符&
不是隐式声明的。
运算符&
永远不要重载它。我不明白从第一个引号中可以看出,用户提供的默认构造函数不能与隐式定义的构造函数“等效”(这是OP的问题)。我不完全理解第二句话,但也不能完全理解其中的联系。@PeterA.Schneider,对于OP的用例,在代码级别,它们显然是相同的。这还取决于您对“等价性”的定义我的意思是,编译器在创建类表示时会做出某些假设,如果用户显式声明和定义特殊成员,则可能不会做出某些假设functions@PeterA.Schneider…我修改了我的回答我知道你认为编译器会做出假设,而你不会hink该标准对隐式默认、显式默认和用户提供的特殊成员函数作了不同的陈述。我只是不明白第一个引号如何做出用户提供的ctor不能满足的假设。隐式与显式默认定义的详细信息是不相关的,因为没有显式默认的func只要用户提供的函数是沿着隐式函数(例如wrt异常规范)仔细声明和定义的,我看没问题。另外,从本体论的角度来看:编译器做出的假设我们不知道;我们唯一得到的提示是生成的代码。如果代码是相同的,我们可以安全地假设,为了奥卡姆的缘故,编译器的基本假设、道德价值观和宇宙观也是相同的。