🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

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

Q&A

3回答

1042閲覧

c++でN個の引数のうち一部または全部に値を渡し、残りはデフォルト値にしたい

sasa3

総合スコア5

C++

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

0グッド

1クリップ

投稿2021/03/22 05:12

編集2021/03/22 07:34

実現したい機能

c++において最大でN個の引数を取る関数をつくり、その引数の一部または全部に値を渡し、残りをデフォルト値とすることは可能でしょうか。但し、受ける引数は全て型が異なります。イメージとしては以下のような機能を実装したいです。

c++

1func(T1 n1=v1, T2 n2=v2, T3 n3=v3,...,TN nN=vN) {} 2 3main 4{ 5T2 val2 = hoge; 6func(val2); 7// n1, n2, n3,..., nN = v1, hoge, v3,..., vN 8 9T3 val3 = fuga; 10func(val2, val3) 11// n1, n2, n3,..., nN = v1, hoge, fuga,..., vN 12}

追記:

型T1からTNは継承関係にはありません。(継承関係にある場合どう変わるかも興味があります)

具体的にやりたいことですが、センサーモジュールのコンフィグを書き換える関数を作っていまして、基本的にはデフォルト値を書き込めば良いのですが、場合によっては一部のコンフィグを変更する必要があります。但し、コンフィグの書き換え順序に制約があり、個々のコンフィグを書き換える関数を作るよりは全体をまとめて書き換える関数の方が使い勝手が良いのです。
したがって型T1からTNはセンサーの機能毎のコンフィグをまとめた構造体になります。

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

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

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

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

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

yumetodo

2021/03/22 07:17

受ける引数は全て型が異なりますとのことですが、n番目の引数に取りうる型は継承関係にあったりはしないのでしょうか?もうちょっとどういうことをやりたいか全体的な話があると良い解決策が提示できると思います。
guest

回答3

0

C++20で導入された 指示付き初期化構文 を利用し、デフォルト値ありのキーワード引数風の記述を行うことはできます。この実装では引数型Tnを問いません。一方、関数呼び出し時の名前指定順は宣言順(abc)に並べる必要があります。

Demo: https://wandbox.org/permlink/dePzSyhX7H2inWgK

cpp

1#include <iostream> 2 3struct FuncArgs { 4 int a = 1; 5 int b = 2; 6 int c = 3; 7}; 8 9void Func(FuncArgs args = {}) 10{ 11 std::cout 12 << "a=" << args.a << ", " 13 << "b=" << args.b << ", " 14 << "c=" << args.c << std::endl; 15} 16 17int main() 18{ 19 Func(); 20 Func({.b = 200}); 21 Func({.a = 100, .c = 300}); 22}

C++17以前であれば、Boost.Parameterライブラリという選択肢もあります。

投稿2021/03/23 14:50

編集2021/03/24 00:20
yohhoy

総合スコア6191

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

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

0

やりたいことと違う気もしますが…

C++

1//こんなのを用意して… 2struct Arguments 3{ //各要素のデフォルト値を与えておく 4 T1 n1 = v1; 5 T2 n2 = v2; 6 ... 7 TN nN = vN; 8}; 9 10//引数を↑の型にしたオーバーロードを用意してやる 11func( const Arguments &Args ) 12{ //大元の関数に渡す 13 func( Args.n1, Args.n2, ... Args.nN ); 14}

投稿2021/03/22 08:01

fana

総合スコア11985

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

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

yumetodo

2021/03/22 09:17

ビルダーパターンに近いこれがやっぱり最適解に思える・・・
fana

2021/03/22 09:58 編集

Arguments &operator()( const T1 &t1 ){ n1=t1; return *this; } みたいなのを全要素分用意すれば func( Arguments()( T5(略) )( T3(略) ) ); みたく順不同括弧乱舞で書けて便利なのだろうか?
yumetodo

2021/03/22 09:58

あーRustじゃないから確かにoperator()という手はある(なお可読性は
fana

2021/03/22 10:05

> Arguments()( T5(略) )( T3(略) ) の最初の括弧が何か嫌だ → せっかくだから Arguments( const T1 &n1 ) : n1(n1) {} も要素個数分だけ追加ということで.
yumetodo

2021/03/22 14:56

でもそこまで来ると質問者さんが言ってるように可変長引数でconstexpr if使って分岐するほうがいいような気もしてくる・・・
guest

0

「C++ デフォルト引数」でぐぐれば、そこらへんの説明が出てきますよ

投稿2021/03/22 05:26

y_waiwai

総合スコア88038

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

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

sasa3

2021/03/22 06:41

デフォルト値については理解しています。 その上で上のような機能を実装するにはどのような手段を取るべきか考えています。 現在考えているのはvariadic templateで受けて展開し、型によって処理を変えるようにすれば良いかと思ったのですが、もう少しマシなやり方は無いものかと質問しました。 言葉が不足していて申し訳ないです。
y_waiwai

2021/03/22 07:27

ああ、こちらが勘違いしてたようですね そういう場合はオーバーロードでその分メソッドをつくってやるってはなしになりそうですね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問