samedi 1 octobre 2016

How to control when initializer_list is used. Local vars, returning, and passing args.

When writing code, I'm usually very clear in my own mind about whether or not I want to call a constructor that has a single initializer_list constructor. But I often don't feel confident when writing code that I can specify what will happen. There appear to be changes planned for c++17, around auto, which simply add to my paranoia. I don't want to understand all the corners cases to understand everybody else's code. I just hope to fix some simple rules for writing code.

Pre-question: Is there a convenient name for constructors that have exactly one argument, which is of type std::initializer_list<T>? This constructor appears to be 'special', so it should have a clear name.

Are there any simple rules-of-thumb to ensure that the desired behaviour is achieved? Perhaps something like:

  • (This is just a hypothetical list, probably incorrect)

  • a return followed by a { will always call the init-list constructor (if present)

  • in a variable definition, = followed by { will also prefer the init-list constructor

  • foo(3, ???, true) will construct the second arg of foo as an init-list if ??? takes this form (beginning with { I guess)

And of course, I also would like to be able to do the opposite consistently. If returning a vector<int> for example, how do I return in such a way that I get the non-init-list constructors? (And also avoid the most-vexing-parse, of course!).

I can see three scenarios where this is relevant. Initializing variables in a function, returning from a function, and passing args to a function. And I guess there are other interesting places too.

If we can identify a few non-ambiguous patterns that cover all these use-cases, which behave the same in c++11/14/17, then I would simply avoid any code that doesn't match that pattern and replace it with something that is clear to me.

Aucun commentaire:

Enregistrer un commentaire