質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2456閲覧

可変長引数テンプレートが思うように展開されない

Himatya1

総合スコア11

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/01/22 19:07

###発生している問題
可変長テンプレートを使い、引数から受け取った変数を用いて配列の初期化を行おうとしたのですが、
配列の中身が全て0になってしまいました。

どうすれば関数に入力した引数と同じ値を入れることができるでしょうか?

よろしくお願いします。

###該当のソースコード

C++

1//問題の関数 2template<class T, std::size_t N, T... i> 3void hoge0(const T (&v)[N]){ 4 T dxx[N] = {v[i] ...}; 5 for(T x : dxx) 6 std::cout << x << ","; 7 std::cout << std::endl; 8} 9 10//これはうまくいく 11void hoge1(const int (&v)[5]){ 12 int dxx[5] = {v[0], v[1], v[2], v[3], v[4]}; 13 for(T x : dxx) 14 std::cout << x << ","; 15 std::cout << std::endl; 16} 17 18int main(){ 19 hoge0({0, 1, 2, 3, 4}); 20 hoge1({0, 1, 2, 3, 4}); 21} 22

####出力

0,0,0,0,0, 0,1,2,3,4,

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

うまくいかない理由は、hoge0の実引数に、パラメータパックiに対応するものが渡されていないため、「型推論」できません。
そもそも非型パラメータなので「型推論」は使えないようにも感じます。

静的処理が必要なので意外に配列の展開は難しいです。


C++11テクニック☆ 配列を配列で初期化する方法+α

を参考にして、開発中のソフトで良く似た処理をしたことがあります。
それを使ってできました。

C++

1#include <iostream> 2 3//問題の関数 4template<class T, std::size_t N, T... i> 5void hoge0(const T (&v)[N]){ 6 std::cout << "hoge0() count=" << sizeof...(i) << "\n"; 7 T dxx[N] = {v[i] ...}; 8 for(T x : dxx) 9 std::cout << x << ","; 10 std::cout << std::endl; 11} 12 13//これはうまくいく 14void hoge1(const int (&v)[5]){ 15 int dxx[5] = {v[0], v[1], v[2], v[3], v[4]}; 16 for(int x : dxx) 17 std::cout << x << ","; 18 std::cout << std::endl; 19} 20 21//-------------------------------------------- 22#include <iostream> 23 24template<std::size_t... tIndices> 25struct IndicesHolder 26{ 27 typedef IndicesHolder<tIndices..., sizeof...(tIndices)> Next; 28}; 29 30template<std::size_t tIndexCount> 31struct MakeIndices 32{ 33 typedef typename MakeIndices<tIndexCount-1>::Type::Next Type; 34}; 35 36template<> 37struct MakeIndices<0> 38{ 39 typedef IndicesHolder<> Type; 40}; 41 42template<typename tElementType, std::size_t tDim> 43struct ArrayBody 44{ 45 tElementType mElements[tDim]; 46 47 template<typename tArraySingleDimension, std::size_t... tIndices> 48 ArrayBody(tArraySingleDimension& iData, IndicesHolder<tIndices...>) : 49 mElements{iData[tIndices]...} 50 { } 51 52 // 範囲ベースfor用 53 tElementType* begin() { return &mElements[0]; } 54 tElementType* end() { return &mElements[tDim]; } 55 56 // 要素取り出し 57 tElementType& operator[](std::size_t i) 58 { 59 return mElements[i]; 60 } 61}; 62 63template<class T, std::size_t N> 64void hoge2(const T (&v)[N]){ 65 std::cout << "hoge2()\n"; 66 ArrayBody<T, N> dxx{v, typename MakeIndices<N>::Type()}; 67 for(T x : dxx) 68 std::cout << x << ","; 69 std::cout << std::endl; 70 71 for (std::size_t i=0; i < N; ++i) 72 std::cout << dxx[i] << ","; 73 std::cout << std::endl; 74} 75//-------------------------------------------- 76 77int main(){ 78 hoge0({0, 1, 2, 3, 4}); 79 hoge1({0, 1, 2, 3, 4}); 80 hoge2({0, 1, 2, 3, 4}); 81}

実行結果:

txt

1hoge0() count=0 20,0,0,0,0, 30,1,2,3,4, 4hoge2() 50,1,2,3,4, 60,1,2,3,4,

MinGW 5.4.0(-std=c++11)とmsvc 2015で動作確認しました。

投稿2017/01/23 03:20

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問