1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C++での擬似的な名前付き引数(c++20版)

Last updated at Posted at 2020-07-03

はじめに

関数の引数が増えるとデフォルト値が指定してあっても、途中の引数だけでデフォルト値を指定することはできない。そのため、結局デフォルト値を調べながら指定する必要ある。kotlinなど名前付き引数がある言語なら、個別にパラメータを指定できてうらやましいところだが、c++20で指示付き初期化子(designated initialization)が規格され、これを使うと擬似的に名前付き引数が使える。c++17以前版は記事にまとめたので、改めてc++20版としてまとめなおした。
なお、c++17以前の機能を使ったものに関しては以下を参照
https://qiita.com/luftfararen/items/0a0c81ae2418a896691f

実装例と使い方

main.cpp

# include <string>
# include <iostream>
# include <iomanip>
# include <sstream>
# include "named_args.h"

//引数のリストは構造体として定義し、デフォルト値を指定
struct to_str_args
{
	int base = 10;
	int w=0;
	int precision = 5;
	char fill = ' ';
	bool fixed = false;
};

template<class T>
std::string to_str(T v, const to_str_args& a = to_str_args())
{
	std::stringstream ss;
	ss << std::setfill(a.fill);
	ss << std::setbase(a.base);
	ss << std::setw(a.w);
	if (a.fixed) ss << std::fixed;
	ss << std::setprecision(a.precision);
	ss << v;
	return ss.str();
}


int main()
{
	std::cout << to_str(12.345) << std::endl; //(1)
	std::cout << to_str(12.345, {.w = 6 }) << std::endl;//(2)
	std::cout << to_str(12.345, {.w = 7, .precision = 3,.fill = '0' }) << std::endl;//(3)

	to_str_args a{.w = 7, .precision = 3,.fill = '0' };
	std::cout << to_str(12.345, a) << std::endl;//(4)
	std::cout << to_str(23.456, a) << std::endl;//(5)
}

結果

12.345
012.345
00012.3
00012.3
00023.5

解説

(1)のように構造体変数[(2)と違い{}そのもの]を省略すれば構造体のデフォルト値が使われる。これはto_str関数の引数の構造体変数に、構造体のコンストラクタをデフォルト値として指定しているため。
(2)(3)では、指示付き初期化子を使うことで擬似的に名前付き引数を実現。designated initializationは{}のなかで、"."+メンバ変数=値で初期化する。各メンバの初期化はカンマで区切る。メンバ変数の順番は構造体の定義順でなくてはいけないが省略は可能。
(4)(5)では、構造体変数をそのものを渡している。定義した関数をconst参照で受けているのは、このケースで効率化を図るため。同じパラメータセットを使いまわすときに便利。

さいごに

「構造体を定義するなら、名前付きに引数にする必要ない」じゃんというツッコミは、許して下さい。呼び出し側の記述量はかなり減らせるはず。あと文字列の書式を整えるなら、c++20からは、std::formatがあるので今回の例はあくまで例ということで。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?