2016-03-26 10 views
2

本質的には、一定の内容を保持するために、サイズがテンプレートパラメータである配列を持つテンプレートクラスが必要です。等コンストラクタパラメータからテンプレートメンバ配列を初期化するにはどうすればよいですか?

何か:私は検索ビットをいじり、ほとんど回避策は、中間静的メソッドで実装しているとstd ::アレイを使用している

template<size_t S> struct Foo { 
    const int bar[S]; 
    Foo(const int(&par)[S]) : bar(par) { 
     cout << "bar size is " << S << endl; 
    } 
}; 
auto foo = Foo({1,2,3}); 

template<size_t S> struct Baz { 
    const array<int,S> qux; 
    Baz(const array<int,S>&par) : qux(par) { 
    cout << "size is " << S << endl; 
    } 
}; 
template<size_t S> Baz<S> 
GetBaz(const array<int,S>&in) { 
    return Baz<S>(in); 
} 

int main() { 
    auto sample = GetBaz({1,2,3}); 
    return 0; 
} 

..既にかなりの定型文ですが、std :: arrayは初期化子のリストから構築されていないようですね。 。?:-(

prog.cpp: In function 'int main()': 
prog.cpp:27:30: error: no matching function for call to 'GetBaz(<brace-enclosed initializer list>)' 
    auto sample = GetBaz({1,2,3}); 
+0

あなたは、アレイに内蔵され、STD :: '自動サンプルについて –

+0

をarray''使用しなければならないでこれを行うことはできません= GetBaz({1,2,3}); 'GetBaz <5> 'などを指定する必要があるため、失敗します。イニシャライザのリストの長さは、その型の一部ではありません。 –

+1

[この回答のコード](http://stackoverflow.com/a/6114359/1505939)は、 'GetBaz(1,2,3)'を余分なものなしで使用したい場合、あなたの問題を解決するのに役立ちます中括弧 –

答えて

5

ポストDR1591内蔵の配列は、今ブレース-のinit-リストから推論されていますそう:

template<size_t S> struct Baz { 
    const array<int,S> qux; 
    Baz(const array<int,S>&par) : qux(par) { 
    cout << "size is " << S << endl; 
    } 
    Baz(const int (&par)[S]) : qux(std::experimental::to_array(par)) {} 
}; 

template<size_t S> Baz<S> 
GetBaz(const int (&in)[S]) { 
    return Baz<S>(in); 
} 

std::experimental::to_arrayビルトイン1からstd::arrayを作成します。実装については、リンクされたcppreferenceページを参照してください。

あなたは、組み込み配列にすべての道を行くことができますが、それは幾分迷惑なんだ:

template<size_t S> struct Baz { 
    const int bar[S]; 

    template<size_t... Is> 
    Baz(const int (&par)[S], std::index_sequence<Is...>) 
     : bar { par[Is]... } {} 

    Baz(const int (&par)[S]) : Baz(par, std::make_index_sequence<S>()) {} 
}; 

template<size_t S> Baz<S> 
GetBaz(const int (&in)[S]) { 
    return Baz<S>(in); 
} 
+0

ありがとう、私は 'experimental'を使用するファンではありませんが、あなたの答えは非常に明確であり、質問に答えています。 – gatopeich

+0

ところで、古いスタイルの配列と同等のことは分かっていますか?私はまだstd :: arrayが何かを改善する代わりに追加された理由をまだ理解していません。 – gatopeich

+0

@gatopeich編集を参照してください。 –

2

ない私は完全に質問を理解している場合あなたが達成しようとしているかということです

#include <iostream> 
#include <array> 

template<size_t S> struct Baz { 
    const std::array<int,S> qux; 
    Baz(const std::array<int,S>& par) : qux(par) { 
     std::cout << "size is " << qux.size() << std::endl; 
    } 
}; 

int main() { 
    auto sample = Baz<5>({1,2,3}); // size = 5, values = 1, 2, 3, 0, 0 
    return 0; 
} 

概要:

  1. ではなく、生のstd::arrayを使用します配列
  2. テンプレートの引数を指定します。例:Baz<5>(...) クラステンプレートar記念碑は推論されません。
+0

正確には、私は配列のサイズを推定したい:-)。クラステンプレートの引数はコンストラクタ_から推論できないことは知っていますが、静的関数 'GetBaz()'を使用する準備ができています。私がうまくいく方法で解決できない問題は、初期化子リストを中間関数を介してコンストラクタに渡すことです。 – gatopeich

0

あなたは、古典的なC配列でそれを行うことができますが、可変引数コンストラクタを使用すると、バインド

#include <array> 
#include <cstddef> 
#include <iostream> 

using namespace std; 

template <size_t S> struct Foo { 
    const int bar[S]; 
    const std::array<int, S> bar2; 

    template <typename ... I> 
     Foo (const I & ... i) : bar {i...}, bar2 {{i...}} 
    { 
     cout << "bar size is " << S << " == " << 
     (sizeof(bar)/sizeof(bar[0])) << " == " << bar2.size() << endl; 
    } 
}; 

int main() 
{ 
    Foo<3> foo {1,2,3}; 

    auto foo2 = Foo<4>{1,2,3,4}; 

    return 0; 
} 
関連する問題