9

I like c++11 variadic templates, so I often write some little codes with it.

See this example:

#include <cstdio>
#include <type_traits>
#include <vector>

template< typename ... T >
auto make_vector(T ... t ) -> std::vector< typename std::common_type<T...>::type >
{
    std::vector< typename  std::common_type<T...>::type > v;
    v.reserve( sizeof...(T) );

    using list = int[];
    (void)list{ 0, ( (void)v.push_back(std::move(t)) ,0)... };
    //                |/ / / /
    //                --------
    //                 \-- How are evaluated v.push_back()s, sequentially or arbitrary ?
    return v;
}

int main()
{
    auto v = make_vector(2, 3.0, 'a', 7UL );

    for(auto e : v )
      printf("%.2lf ", e);

    printf("\n");

}

Q: Is evaluation order of initialization of array sequentially or arbitrary (or implementation defined, undefined behavior) ?

If make_vector is wrong, how me fix its?

3
  • 1
    @Khurshid: +1 for the question. As an aside, why push_back? Why not construct the vector directly? return {std::forward<typename std::common_type<T...>::type>(t)...}; Commented Nov 25, 2013 at 9:00
  • @GMan: Nope, braced-init-lists are specifically sequenced left-to-right, even if that evaluates to a normal constructor call. It has also always been left-to-right for aggregate initialization. Commented Nov 25, 2013 at 9:26
  • @Xeo: Read it as a function call for some reason, my mistake! Commented Nov 25, 2013 at 10:23

1 Answer 1

13

They are evaluated sequentially. C++11 § 8.5.4 [dcl.init.list] paragraph 4:

Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions (14.5.3), are evaluated in the order in which they appear.

Given that vector has an initializer_list constructor, you could simplify your function to:

template <typename ... T>
auto make_vector(T ... t) ->
  std::vector< typename std::common_type<T...>::type >
{
  return { static_cast<typename std::common_type<T...>::type>(t)... };
}

and not have to worry about arcane initialization semantics ;)

Sign up to request clarification or add additional context in comments.

2 Comments

Using std::forward you can do away with the cast too :)
C11 port70.net/~nsz/c/c11/n1570.html#6.7.9p23 - The evaluations of the initialization list expressions are indeterminately sequenced with respect to one another and thus the order in which any side effects occur is unspecified.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.