可変長引数テンプレートが思うように展開されない
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 1,789
発生している問題
可変長テンプレートを使い、引数から受け取った変数を用いて配列の初期化を行おうとしたのですが、
配列の中身が全て0になってしまいました。
どうすれば関数に入力した引数と同じ値を入れることができるでしょうか?
よろしくお願いします。
該当のソースコード
//問題の関数
template<class T, std::size_t N, T... i>
void hoge0(const T (&v)[N]){
T dxx[N] = {v[i] ...};
for(T x : dxx)
std::cout << x << ",";
std::cout << std::endl;
}
//これはうまくいく
void hoge1(const int (&v)[5]){
int dxx[5] = {v[0], v[1], v[2], v[3], v[4]};
for(T x : dxx)
std::cout << x << ",";
std::cout << std::endl;
}
int main(){
hoge0({0, 1, 2, 3, 4});
hoge1({0, 1, 2, 3, 4});
}
出力
0,0,0,0,0,
0,1,2,3,4,
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
こんにちは。
うまくいかない理由は、hoge0の実引数に、パラメータパックiに対応するものが渡されていないため、「型推論」できません。
そもそも非型パラメータなので「型推論」は使えないようにも感じます。
静的処理が必要なので意外に配列の展開は難しいです。
を参考にして、開発中のソフトで良く似た処理をしたことがあります。
それを使ってできました。
#include <iostream>
//問題の関数
template<class T, std::size_t N, T... i>
void hoge0(const T (&v)[N]){
std::cout << "hoge0() count=" << sizeof...(i) << "\n";
T dxx[N] = {v[i] ...};
for(T x : dxx)
std::cout << x << ",";
std::cout << std::endl;
}
//これはうまくいく
void hoge1(const int (&v)[5]){
int dxx[5] = {v[0], v[1], v[2], v[3], v[4]};
for(int x : dxx)
std::cout << x << ",";
std::cout << std::endl;
}
//--------------------------------------------
#include <iostream>
template<std::size_t... tIndices>
struct IndicesHolder
{
typedef IndicesHolder<tIndices..., sizeof...(tIndices)> Next;
};
template<std::size_t tIndexCount>
struct MakeIndices
{
typedef typename MakeIndices<tIndexCount-1>::Type::Next Type;
};
template<>
struct MakeIndices<0>
{
typedef IndicesHolder<> Type;
};
template<typename tElementType, std::size_t tDim>
struct ArrayBody
{
tElementType mElements[tDim];
template<typename tArraySingleDimension, std::size_t... tIndices>
ArrayBody(tArraySingleDimension& iData, IndicesHolder<tIndices...>) :
mElements{iData[tIndices]...}
{ }
// 範囲ベースfor用
tElementType* begin() { return &mElements[0]; }
tElementType* end() { return &mElements[tDim]; }
// 要素取り出し
tElementType& operator[](std::size_t i)
{
return mElements[i];
}
};
template<class T, std::size_t N>
void hoge2(const T (&v)[N]){
std::cout << "hoge2()\n";
ArrayBody<T, N> dxx{v, typename MakeIndices<N>::Type()};
for(T x : dxx)
std::cout << x << ",";
std::cout << std::endl;
for (std::size_t i=0; i < N; ++i)
std::cout << dxx[i] << ",";
std::cout << std::endl;
}
//--------------------------------------------
int main(){
hoge0({0, 1, 2, 3, 4});
hoge1({0, 1, 2, 3, 4});
hoge2({0, 1, 2, 3, 4});
}
実行結果:
hoge0() count=0
0,0,0,0,0,
0,1,2,3,4,
hoge2()
0,1,2,3,4,
0,1,2,3,4,
MinGW 5.4.0(-std=c++11)とmsvc 2015で動作確認しました。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.09%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる