In-class member initializer using a constructor: is it allowed?

199 Views Asked by At

I recently found an interesting piece of code in the article Get to Know the New C++11 Initialization Forms by Danny Kalev:

class C
{
string s("abc");
double d=0;
char * p {nullptr};
int y[5] {1,2,3,4};
public:
C();
};

The line string s("abc"); seems suspicious to me. I thought that using a constructor is not allowed while a member is initialized in-class. And this code (simplified to class C { string s("abc"); };`) doesn't compile with

  • clang 3.6.1 (compiler arguments are -std=c++11 -Wall -Wextra -Werror -pedantic-errors)
  • g++ 5.1.0 (compiler arguments are the same: -std=c++11 -Wall -Wextra -Werror -pedantic-errors)
  • vc++ 18.00.21005.1 (compiler arguments are /EHsc /Wall /wd4514 /wd4710 /wd4820 /WX /Za)
  • vc++ 19.00.22929.0 (compiler arguments are predefined by the service: /EHsc /nologo /W4 /c)

Am I right and there is an error in this article?

2

There are 2 best solutions below

6
On BEST ANSWER

Am I right and there is an error in this article?

Yes, it is an error in the article.

Only a brace-or-equal-initializer is allowed in the declaration of a data member. The initializations of d, p, and y are correct, but not s. The rationale for this is that using an expression-list would ambiguate the declaration with a function declaration and it would also cause conflicts with name lookup in the class body.

0
On

An example from Bjarne Stroustrup:

class A {
    public:
        A() {}
        A(int a_val) : a(a_val) {}
        A(D d) : b(g(d)) {}
        int a = 7;
        int b = 5;  
    private:
        HashingFunction hash_algorithm{"MD5"};  // Cryptographic hash to be applied to all A instances
        std::string s{"Constructor run"};       // String indicating state in object lifecycle
    };