9

私は C++11 の可変個引数テンプレートが好きなので、それを使って小さなコードを書くことがよくあります。

次の例を参照してください。

#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: 配列の初期化の評価順序は順次ですか、それとも任意 (または実装定義、未定義の動作) ですか?

間違っている場合、どうすればmake_vector 修正できますか?

4

1 に答える 1

12

それらは順番に評価されます。C++11 § 8.5.4 [dcl.init.list] 段落 4:

braced-init-listinitializer-list内で、pack展開 (14.5.3) の結果を含むinitializer-clausesは、出現順に評価されます。

vectorコンストラクターがある場合、関数initializer_listを次のように単純化できます。

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)... };
}

難解な初期化セマンティクスについて心配する必要はありません;)

于 2013-11-25T07:27:21.323 に答える