2

C++11 を使用して、コンストラクターを使用して、以下のinitializer_listような再帰的に定義されたクラスをアセンブルすることは可能ですか?Fooconstexpr

template <size_t N>
struct Foo {
  constexpr Foo(int x, Foo<N-1> f) : x(x), xs(xs) {}
  int x;
  Foo<N-1> xs;
};

template <> struct Foo<0> {};

Foo<3>次を使用して初期化できます。

int main(int argc, char *argv[])
{
  Foo<3> a = Foo<3>(1,Foo<2>(2,Foo<1>(3,Foo<0>())));
  return 0;
}

代わりに Foo<3> a = {1,2,3} を使用するとよいでしょう。constexpr tail機能があれば、initializer_listうまくいくはずです。

4

3 に答える 3

9

はい、一種のラウンドアバウトな方法で、イニシャライザリストを効果的にアンパックして、より適切な形式に再パックします。ただし、より良い (imho) 方法があります: Variadic テンプレートです。

#include <stddef.h>
#include <iostream>

template <size_t N>
struct Foo {
  template<class... Tail>
  constexpr Foo(int i, Tail... t) : x(i), xs(t...) {}

  void print(){
    std::cout << "(" << x << ", ";
    xs.print();
    std::cout << ")";
  }

  int x;
  Foo<N-1> xs;
};

template <> 
struct Foo<1> {
  constexpr Foo(int i) : x(i) {}
  void print(){ std::cout << "(" << x << ")"; }
  int x;
};

int main(){
 Foo<3> x = {1, 2, 3};
 x.print();
 std::cout << "\n";
}

期待どおりの出力:

(1, (2, (3)))

基本ケースとして選択したことに注意してください1。単純に、より理にかなっています。

于 2012-03-13T00:09:53.803 に答える
1

私はそれをコンパイルできるコンパイラを持っていませんが、正しい答えは次のようなものだと思います:

template <size_t N>
struct Foo {
  constexpr Foo(int x, Foo<N-1> f)   //template iterator constructor
  : x(x), xs(xs) {}
  Foo(std::initializer_list<int> f)  //initializer list constructor
  : x(*f.begin()), xs(++f.begin(), f.end()) 
  { static_assert(xs.size()==N, "incorrect number of values in initializer list");}
  template<class iter>
  Foo(iter first, iter last)  //template iterator constructor
  : x(*first), xs(++first, last) {}  //UB if wrong number of values given

  int x;
  Foo<N-1> xs;
};

template <> 
struct Foo<1> { //I use 1 for smaller structures
  constexpr Foo(int f) 
  : x(f) {}
  Foo(std::initializer_list<int> f) 
  : x(*f.begin())
  { static_assert(xs.size()==1, "incorrect number of values in initializer list");}
  template<class iter>
  Foo(iter first, iter last)
  : x(*first)
  { assert(first+1 == last); } 

  int x;
};

再帰的な構造の場合、イニシャライザ リストは、イテレータを受け取るコンストラクタに再帰的に渡す必要があります。

于 2012-03-13T00:17:42.390 に答える