5

I am trying out the various ways of creating std::vector on the fly and passing it to another function:

#include <iostream>
#include <vector>

void print(std::vector<int> a)
{
    std::cout << a.size() << '\n';
}

int main()
{
    print({1, 2, 3, 4, 5});
    print(std::vector<int>{1, 2, 3, 4, 5});
    print(std::vector<int>({1, 2, 3, 4, 5}));
}

This produces the desired output:

$ clang++ -std=c++11 foo.cpp && ./a.out
5
5
5

I want to know what are the differences between these three invocations:

print({1, 2, 3, 4, 5});
print(std::vector<int>{1, 2, 3, 4, 5});
print(std::vector<int>({1, 2, 3, 4, 5}));

Here is another example:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> a = {1, 2, 3, 4, 5};
    // std::cout << (a == {1, 2, 3, 4, 5}) << '\n'; // error
    std::cout << (a == std::vector<int>{1, 2, 3, 4, 5}) << '\n';
    std::cout << (a == std::vector<int>({1, 2, 3, 4, 5})) << '\n';
}

Here is the output:

$ clang++ -std=c++11 foo.cpp && ./a.out 
1
1

I am hoping that the answer to this question can become a good reference answer on this topic where the answer discusses the following aspects of these invocations:

  • The above three and any other similar ways of passing a std::vector to another function.
  • Semantic differences between the various methods.
  • Performance differences (if any) between the various methods.
  • Best practices (if any) due to which one invocation is favourable over another.

If you think the question has any shortcomming, please feel free to edit the question and improve it.

Lone Learner
  • 18,088
  • 20
  • 102
  • 200
  • @Someprogrammerdude I'm not sure about the exact terminology, but according to [this](https://stackoverflow.com/questions/485119/what-does-the-word-literal-mean) that can be considered a literal. – user202729 May 20 '18 at 03:10
  • 1
    There are no vector "literals". What's happening is standard [*list-initialization*](http://en.cppreference.com/w/cpp/language/list_initialization), using [`std::initializer_list`](http://en.cppreference.com/w/cpp/utility/initializer_list) with a suitable [`std::vector` constructor](http://en.cppreference.com/w/cpp/container/vector/vector). – Some programmer dude May 20 '18 at 03:10
  • I'm sure I recall a very similar question to this last week? – M.M May 20 '18 at 04:44
  • 1
    @user202729 this is a C++ question, that is a C# question. They are quite different languages despite having superficially similar names – M.M May 20 '18 at 04:59
  • @M.M [tag:language-agnostic] ? – user202729 May 20 '18 at 05:40

1 Answers1

4

Since C++17, all of these have exactly the same effect. The print function is called and the function argument is created by invoking the constructor vector(std::initializer_list<int>).

The first one would probably be considered the preferable syntax since it avoids redundancy.

Prior to C++17 there might have been various temporary objects created and destroyed but that is all in the past now.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Do they have the same effect in the following scenario too: `std::vector a = {1, 2, 3, 4, 5}; std::cout << (a == std::vector{1, 2, 3, 4, 5}) << '\n'; std::cout << (a == std::vector({1, 2, 3, 4, 5})) << '\n';`? – Lone Learner May 20 '18 at 05:52
  • @LoneLearner yes – M.M May 20 '18 at 06:09