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

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

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

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

Q&A

解決済

1回答

1079閲覧

テンプレート型関数をstd::functionに渡す方法がわかりません

jbe00214

総合スコア63

C++

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

0グッド

0クリップ

投稿2021/05/15 14:14

編集2021/05/15 14:22

前提・実現したいこと

 クラス型とスカラー値の混在するシーケンスを可変パラメータとして関数に渡したいのですが,その関数を2つ用意し条件に応じて使い分けを考えています。
例えば以下のコードですが,まず,funcBとfuncCはこの質問の本質部分ではなく,処理のスタブになります。テンプレートパラメータGは受け取る関数でg の処理結果をfuncC に渡して結果を表示します。
次に,funcAですが,funcBの第1引数にラムダ式を渡して,funcBから呼び出します。その際funcBの第2引数以下で渡したvectorと整数が混在したパラメータをfuncB内でラムダ式で処理して型に応じた結果を返します。funcAは期待通り動きます。
問題は,funcAAのように,異なる動作をする関数を2つ用意して条件に応じてfuncBに渡したいというものです。その方法としてstd::functionを考えたのですが,どのようにfunctionのテンプレートに渡すのかがわかりません。functionにこだわりはないので,他の方法でも良い方法があれば教えていただけませんでしょうか。多分テンプレートを渡すのかなと思ったのでタイトルはそのように書きました。

該当のソースコード

C++

1#include<function> 2using namespace std; 3 4template<typename ...Args> 5void funcC(Args...args){for(auto m:{args...})cout << m<< '\n';} 6 7template<typename G, typename ...Args> 8void funcB(G g,Args ...args ){ 9 funcC( g(args)...); 10} 11 12void funcA(){ 13 vector<int> v1,v2; 14 funcB([]( auto v){ 15 if constexpr(is_scalar_v<decltype(v)>) 16 return 100; 17 else return 1;},v1,v2,3); 18} 19 20int main(){ 21 funcA(); 22}

実現したいこと

C++

1void funcAA(bool sw){ 2 vector<int> v1,v2; 3 4 // function<int( ? )> f; 5 if( sw ) 6 f= []( auto v){ 7 if constexpr(is_scalar_v<decltype(v)>) 8 return 100; 9 else return 1;}; 10 else 11 f=[]( auto& v){return 1;}; 12 13 funcB(f,v1,v2,3); 14} 15int main(){ 16 funcAA(true); 17}

補足情報(FW/ツールのバージョンなど)

clang
C++17

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

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

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

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

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

yumetodo

2021/05/15 16:07

ちなみに一度変数fに入れないで直接それぞれでfuncB呼ぶのはなしですか?
jbe00214

2021/05/15 20:25

funcAがそうやってるんですが,最後はそうするか,と思っています。コードが汚くなるので,方法はないかと....
jbe00214

2021/05/15 20:39

あと,もう一つ,実際に現在書いているのは,funcAのような関数ではなく,コンストラクタなんです。fにしておかないと,入れにくいような。関数にする場合,fを渡す関数を2種類用意して呼び出し時に使い分けることになる。最後はこれを検討するかと思っています。
guest

回答1

0

ベストアンサー

クラステンプレートstd::function<R(ArgTypes...)>はその宣言型が表現する通り「戻り値型Rと引数型リストArgTypes...」が固定されるため、質問中にあるような ジェネリックラムダ式 は格納できません。

また(ジェネリック/非ジェネリック問わず)ラムダ式毎に固有のクロージャ型をもつため、1つのラムダ式に処理を押し込んでしまった方が実装が簡素になると思います。

c++

1void funcAA(bool sw){ 2 vector<int> v1,v2; 3 4 auto f = [sw](auto&& v){ 5 if( sw ) { 6 if constexpr(is_scalar_v<decay_t<decltype(v)>>) 7 return 100; 8 else 9 return 1; 10 } else { 11 return 2; 12 } 13 }; 14 funcB(f,v1,v2,3); 15}

投稿2021/05/19 02:59

yohhoy

総合スコア6191

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

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

jbe00214

2021/05/19 07:42

なるほど。スッキリしてイイ感じですね。やってみます。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問