2015-12-11 4 views
6

それでは、私はこのコードを持っているとしましょう:可変要素テンプレート関数の引数としてベクトル要素を渡すにはどうすればよいですか?

template <class T1, class T2> 
auto sum(T1 a, T2 b) ->decltype(a + b) { 
    return a + b; 
} 
template <class T1, class T2, class... T3> 
auto sum(T1 a, T2 b, T3... tail) ->decltype(a + sum(b, tail...)) { 
    return a + sum(b, tail...); 
} 

私はベクトルを渡す方法で機能sumを呼び出すしたいと思います:

vector<double> numbers = { 1, 2, 6, 5 }; 

の引数のリストとして使用すべきことであるが、機能sum。どうやってやるの?この場合、関数sumを呼び出すと、14が返されます。

+1

バリアント関数はコンパイル時に解決され、ベクトルは実行時に決定されるサイズを持ちます。おそらく、あなたはベクトル引数を専門にするべきでしょう。 – jaggedSpire

+1

コンパイル時にサイズが分かっているstd :: arrayも使用できます。 – Brian

+0

@ClaudiuちょうどFYI:あなたのリンクはここにポイントします。 ;-) – jaggedSpire

答えて

9

std::vectorはランタイムビーストです。つまり、ヒープにバッファを割り当て、実行時には通常どんな操作も許可されます。一方、バリデーションテンプレート "pealing"はコンパイル時に行われます。その結果、std::vectorとバリデーショナルテンプレートはやや「ばらばらに」なっています。したがって、ベクトルで望むことをすることはできません。

あなたはベクトルの要素を合計したい場合は、これはstd::accumulateを使用して、実行時に行うことができます。

std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
int sum = std::accumulate(v.begin(), v.end(), 0); 

ブライアンはあなたがとの組み合わせで、コンパイル時の計算にstd::arrayを使用することができ、コメントで述べたようにconstexpr機能。あなたがこれを行うことができる方法の例を以下に表示されます。上記の例で

namespace detail { 
template <class T1, class T2> 
constexpr auto sum_(T1 a, T2 b) { 
    return a + b; 
} 
template <class T1, class T2, class... T3> 
constexpr auto sum_(T1 a, T2 b, T3... tail) { 
    return a + sum_(b, tail...); 
} 

template <typename T, std::size_t N, std::size_t... Is> 
constexpr T sum_impl(std::array<T, N> const &src, std::index_sequence<Is...>) { 
    return sum_(src[Is]...); 
} 

} 

template <typename T, std::size_t N> 
constexpr T sum(std::array<T, N> const &arr) { 
    return detail::sum_impl(arr, std::make_index_sequence<N>{}); 
} 

Live Demo

私はあなたのsum機能constexprをマーク。 std::make_index_sequenceを使用して、配列の要素をvariadicのsum関数の引数としてどのように使うことができるかを理解することもできます。

関連する問題