Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Inline" static declaration of object with initializer list

Tags:

c++

c++11

vector

Sorry for the awkward title, but I couldn't find a better one.

Consider this sample code (it has no purpose except illustrating the question):

#include <vector>

void FooBar(int);

void func1()
{
    static std::vector<int> vec {1, 2, 3, 4};

    for (auto & v : vec)
      FooBar(v);
}

void func2()
{
    for (auto & v : std::vector<int> {1, 2, 3, 4})
      FooBar(v);
}

The disassembly of this can be found here

In func1 the static vec vector is supposed to be constructed once and for all at startup. Actually the disassembly on godbolt mentioned above shows that the initialisation of the static vec is done only upon the first call of func1 and not at startup, but that's not the point here.

Now consider func2: here the vector is directly declared "inline" (not sure how this is actually called) inside the for statement, but of course that vector is constructed every time func2 is called.

Is there a way to declare that vector statically and inside the for statement, like for (auto & v : static std::vector<int> { 1, 2, 3, 4}) which is unfortunately not legal C++.

like image 669
Jabberwocky Avatar asked Dec 20 '17 16:12

Jabberwocky


People also ask

What are initializers in C++?

An initializer is an optional part of a data declaration that specifies an initial value of a data object. The initializers that are legal for a particular declaration depend on the type and storage class of the object to be initialized.

What is std :: initializer_list?

An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type const T .

Why do we use initializer list in C++?

When do we use Initializer List in C++? Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.

What is braced init list in C++?

initializer_list constructorsThe initializer_list Class represents a list of objects of a specified type that can be used in a constructor, and in other contexts. You can construct an initializer_list by using brace initialization: C++ Copy. initializer_list<int> int_list{5, 6, 7}; Important.


1 Answers

This won't actually help you yet. But there's something you can do in C++2a. It is, however, based on something that exists already in C++14 and C++17.

C++2a added an init-statement to the range based for loop. That's the new bit, the old bit is that it's the same init-statement as it is defined today. And the definition is as follow ([stmt.stmt]):

init-statement:
    expression-statement
    simple-declaration

What I'm going for is that a simple-declaration may contain a static qualifier. Yup, it does what you'd expect. So in C++2a you may write:

for (static std::vector<int> vec {1, 2, 3, 4}; int v : vec) {
   // Do things.
}

And if you want to test compiler support for it today, here's a C++17 kludge:

if (static std::vector<int> vec {1, 2, 3, 4}; true) {
    // init-statement in if was added in C++17
  for(int v : vec)
    FooBar(v);
}

And its disassembly.

like image 155
StoryTeller - Unslander Monica Avatar answered Oct 04 '22 18:10

StoryTeller - Unslander Monica