Initializing structs in C++

后端 未结 5 908
余生分开走
余生分开走 2020-12-30 21:19

As an addendum to this question, what is going on here:

#include 
using namespace std;

struct A {
    string s;
};

int main() {
    A a = {0}         


        
5条回答
  •  死守一世寂寞
    2020-12-30 22:02

    0 is a null pointer constant

    S.4.9:

    A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero.

    A null pointer constant can be converted to any other pointer type:

    S.4.9:

    A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type

    What you gave for the definition of A is considered an aggregate:

    S.8.5.1:

    An aggregate is an array or a class with no user-declared constructors, no private or protected non-static data members, no base classes, and no virtual functions.

    You are specifying an initializer clause:

    S.8.5.1:

    When an aggregate is initialized the initializer can contain an initializer-clause consisting of a brace enclosed, comma-separated list of initializer-clauses for the members of the aggregate

    A contains a member of the aggregate of type std::string, and the initializer clause applies to it.

    Your aggregate is copy-initialized

    When an aggregate (whether class or array) contains members of class type and is initialized by a brace enclosed initializer-list, each such member is copy-initialized.

    Copy initializing means that you have the equivalent to std::string s = 0 or std::string s = 42;

    S.8.5-12

    The initialization that occurs in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and brace-enclosed initializer lists (8.5.1) is called copy-initialization and is equivalent to the form T x = a;

    std::string s = 42 will not compile because there is no implicit conversion, std::string s = 0 will compile (because an implicit conversion exists) but results in undefined behavior.

    std::string's constructor for const char* is not defined as explicit which means you can do this: std::string s = 0

    Just to show that things are actually being copy-initialized, you could do this simple test:

    class mystring
    {
    public:
    
      explicit mystring(const char* p){}
    };
    
    struct A {
      mystring s;
    };
    
    
    int main()
    {
        //Won't compile because no implicit conversion exists from const char*
        //But simply take off explicit above and everything compiles fine.
        A a = {0};
        return 0;
    }
    

提交回复
热议问题