3
struct SalesData {

    SalesData() = default;
    SalesData(const string&s) : bookNo(s) {}

    string bookNo;
    unsigned copies_sold = 0;
    double revenue = 0;
};

While discussing default constructors, primer says we can use the keyword "=default" to make a constructor default just like code above. That keyword can appear with the declaration inside the class, or with the definition outside the class. If the compiler can't use in-class initializers, we can use initializer list just like the second constructor.

But what's the format?

First I tried to use initializer list directly:

SalesData() = default:bookNo(""), copies_sold(1), revenue(2){};

But it can't work, the compiler says there shouldn't be a colon afer "default".

Then I tried to declare the constructor with "=default" in class and define it outside, without using the initializer list:

struct SalesData {
    SalesData() = default;
   /*...*/}

SalesData::SalesData() {
    bookNo = "";
    copies_sold + 0;
    revenue = 0;
}

The compiler says it's an error of redefinition. Then I moved the keyword outside, which the primer says is supposed to be ok:

struct SalesData {
    SalesData();
   /*...*/}

SalesData::SalesData()=default {
    bookNo = "";
    copies_sold + 0;
    revenue = 0;
}

It still failed, the compiler said there should be a semicolon behine the "default".

I've googled for similar questions, but nothing found.

  1. How could the "=default" and initializer list work together?

  2. How should I use the "=default" outside the class body?

halfer
  • 19,824
  • 17
  • 99
  • 186
Dardai
  • 93
  • 6
  • 1
    If you have an initializer list, it is a user defined constructor and not the default version. So just skip the `=default`. – Bo Persson Oct 08 '16 at 08:13
  • 1
    `=default` is used to specify when you want the compiler to generate a constructor/assignment for you. This implies you cannot have a definition of it. It also only applies to default (we need more words), copy and move constructors and the respective assignments, not a user-defined constructor with an initializer_list. – DeiDei Oct 08 '16 at 08:16

3 Answers3

3

If a function is declared =default, you cannot provide an initializer list (for a constructor), nor a function body.

Either the book is wrong or you misunderstood what the book is saying.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Note that the OP is probably referring to aggregate initialization, which is allowed for explicitly defaulted constructors and it does use the initializer list syntax. – DeiDei Oct 08 '16 at 08:19
  • Thanks, now I learn that definition and =default can't work together. However, the C++ primer 5th says, "...Under the new standard, if we want the default behavior, we can ask the compiler to generate the constructor for us by writing =default after the parameter list. **The =default can appear with the declaration inside the class body or on the definition outside the class body**..." So what could the words about declaration and definition mean ? – Dardai Oct 08 '16 at 08:57
  • @Dardai I think it just meant you can write it inside the class like `SalesData() = default;`, or outside like `SalesData::SalesData() = default;`. – songyuanyao Oct 08 '16 at 09:36
2

In certain situations the compiler automatically generates special functions like the default ctor for you. =default is a way to tell the compiler explicitly to generate the function even in a situation where that would not happen automatically.

The point is: You either implement the function yourself as usual or you =default it. You cannot do both for the same function. The only way to influence what the compiler generates is via default initializers like your double revenue = 0;

Compiler generated implementations are available for the default ctor, copy ctor, copy assignment, move ctor, move assignment and destructor. See this answer for more details. SalesData(const string&) is neither of those, so it cannot be =defaulted.

besc
  • 2,507
  • 13
  • 10
  • Thanks, now I learn that definition and =default can't work together. However, the C++ primer 5th says, "...Under the new standard, if we want the default behavior, we can ask the compiler to generate the constructor for us by writing =default after the parameter list. **The =default can appear with the declaration inside the class body or on the definition outside the class body**..." So what could the words about declaration and definition mean ? – Dardai Oct 08 '16 at 08:58
  • @Dardai You can put `=default` in either of those places. It's not using good words though as they are both declarations without `=default`, and definitions with `=default`. (Also there is a semantic difference, the out-of-line situation does not count as *user-provided*) – M.M Oct 08 '16 at 09:17
1

Some additions.

If you do not specify any constructor in your class the compiler generates the default constructor. This constructor just initializes all the members with their default (empty) constructor (naturally if that constructor exists otherwise it runs to compilation error).

If you specify a non-default constructor the compiler does not generate the default one automatically. Here you can find some details:

Conditions for automatic generation of default/copy/move ctor and copy/move assignment operator?

The =default keyword means that you explicitly ask the compiler to generate the default constructor with default body (also if you already specified another one). This means the body of this constructor is created by the compiler not by you. This is the reason why you got compilation error if you tried to define it.

Note that the =default keyword can be used also at destructors.

Community
  • 1
  • 1
Tibor Takács
  • 3,535
  • 1
  • 20
  • 23