Member initialization using delegated constructor

I started testing the C ++ 11 standard, and I found this question that describes how to call your ctor from another ctor in the same class to avoid using the init method or the like. Now I'm trying to do the same with code that looks like this:

HPP:

class Tokenizer { public: Tokenizer(); Tokenizer(std::stringstream *lines); virtual ~Tokenizer() {}; private: std::stringstream *lines; }; 

castes:

 Tokenizer::Tokenizer() : expected('=') { } Tokenizer::Tokenizer(std::stringstream *lines) : Tokenizer(), lines(lines) { } 

But this gives me an error: In constructor 'config::Tokenizer::Tokenizer(std::stringstream*)': /path/Tokenizer.cpp:14:20: error: mem-initializer for 'config::Tokenizer::lines' follows constructor delegation I tried to move the part of Tokenizer () first and last in the list, but that didn't help.

What is the reason for this and how can I fix it? I tried moving lines(lines) to the body using this->lines = lines; and it works great. But I really would like to be able to use a list of initializers.

Thanks in advance!

+85
c ++ gcc c ++ 11 ctor-initializer
Aug 30 2018-12-12T00:
source share
1 answer

When you delegate member initialization to another constructor, there is an assumption that the other constructor fully initializes the object, including all members (i.e. including the lines member in your example). Therefore, you cannot initialize any member again.

Corresponding quote from the Standard (my attention):

(ยง12.6.2 / 6) The mem-initializer list can be delegated to another constructor of the constructor class using any or-decltype class that denotes the constructor class itself. If mem-initializer-id denotes a class of constructors, it should be the only mem-initializer ; the constructor is the delegating constructor, and the constructor selected by the target constructor. [...]

You can get around this by specifying a constructor version that takes arguments first:

 Tokenizer::Tokenizer(std::stringstream *lines) : lines(lines) { } 

and then define the default constructor using delegation:

 Tokenizer::Tokenizer() : Tokenizer(nullptr) { } 

As a rule, you should completely specify the version of the constructor that takes the largest number of arguments, and then delegate it from other versions (using the required default values โ€‹โ€‹as arguments in the deletion).

+106
Aug 30 2018-12-12T00:
source share



All Articles