â» printf
ã¨ãã®ä»²éãã¡ã«é¢ããè¨äºã§ã¯ããã¾ãã
- ãã©ã¼ãããæååã¨ãã©ã¡ã¼ã¿ããã¯
- ã³ã³ãã¤ã«æçæ
- å®è¡æãã©ã¼ãããã使ã
- std::tie()
- std::tupleã®ãã©ã¼ããããªãã·ã§ã³
- åèæç®
ãã©ã¼ãããæååã¨ãã©ã¡ã¼ã¿ããã¯
std::format()
ããã³std::print()
ã®ãã©ã¼ãããæååã¯å
±éã®ãã®ã§ãæååå
ã®{}
ï¼ç½®æãã£ã¼ã«ãï¼ã«å¯¾ãã¦ãä¸ããããå¼æ°ï¼ãã©ã¼ããã対象ã®å¤ï¼ãæåååãããã®ãé çªã«ç½®ãæãã¦ããã¾ãã
// ãã©ã¼ãããæååã®ä¾ std::print("{}", 0); std::print("{}{}{}", 0, 1.0, "2");
ãã®æããã®å¯¾å¿é¢ä¿ã¯ã³ã³ãã¤ã«æã«ãã§ãã¯ããããã©ã¼ãããæååã®{}
ã®æ°ã«å¯¾ãã¦å¼æ°ã足ããªãå ´åã¯ã¨ã©ã¼ã«ãªãã¾ãï¼ãªãããå¤ãã ããªãã¨ã©ã¼ã«ã¯ãªããªãããã§ãï¼ã
std::print("{}{}{}", 0); // ng std::print("{}", 0, 1, 2, 3); // ok
å¼æ°ã®å¤ã¯å®æ°ã§ããå¿
è¦ã¯ãªãå®è¡æã®å¤ã§ãã£ã¦ãå½ç¶åé¡ãªãã®ã§ããããã©ã¼ãããæååãã®ãã®ãããã³ããã«ç¾ãã¦ããç½®æãã£ã¼ã«ã{}
ã®æ°ã¨ãã©ã¼ããã対象ã®å¼æ°ã®æ°ã¯ãã³ã³ãã¤ã«æã«ã³ã¼ãä¸ã§ä¸è´ãã¦ããå¿
è¦ãããã¾ãã
ã©ã¡ããé常ã«ä¾¿å©ã§ããC++20/23以éã¯ææ¾ããªããªããã¨å¿ è³ã§ãããããããèªç¶ã«ä½¿ç¨ãã¦ããã¨ããã©ã¡ã¼ã¿ããã¯ã«å¯¾ãã¦ä½¿ç¨ããããªãæãæ¥ãã§ãããããããããããããã©ã¡ã¼ã¿ããã¯ã®ãã®ç¬ç¹ãªæ§è³ªã«ããä¸çç¸ã§ã¯ãããªããã¨ã«æ°ã¥ãã¾ãã
void any(auto&&...); void f(auto&&... args) { // ã³ã³ãã¤ã«æã«è¦ç´ æ°ã¯åãã constexpr std::size_t N = sizeof...(args); // ããã¯ãã®ãã®ã¯ä»ã«æ¸¡ããªã any(args); // ng any(args...); // ok // ãã©ã¡ã¼ã¿ããã¯ãã®ãã®ã«ã¯åã¯ç¡ã using t = decltype(args); // ng }
ãã©ã¡ã¼ã¿ããã¯ãã®ãã®ã«å¯¾ãã¦ã¯ãµã¤ãºãåå¾ãããã¨ã¨å±éãããã¨ãããããã§ãããåãã¾ãããããªãã¨ã¯ä¸å¯è½ã§ãããã®ãããstd::format()/std::print()
ã§ãããã©ã¡ã¼ã¿ããã¯ãã®ãã®ã渡ãã¦æåååãããã¨ã¯ã§ãã¾ããã
void print_pack(auto&&... args) { std::print("{}", args); // ng // ããã¯ã®å é ã®å¤ã®ã¿ãåºåããã std::print("{}", args...); // okï¼ããã¯ã空ã§ãªããã°ï¼ }
å¤ãåã«ã¯åé¡ãªãã®ã§å é Nåã ãåºåããããã°ããããæãã§ãããã®ããããã¾ãããããã©ã¡ã¼ã¿ããã¯ã«å«ã¾ããå¤ããã¹ã¦åºåãããå ´åã«ããã©ã¼ãããæååãã¹ãæ¸ããããã¨ã¯ã§ããããªãããçæããå¿ è¦ãåºã¦ãããã«æãã¾ãã
ã³ã³ãã¤ã«æçæ
C++17以åã ã¨ã¡ã¿ã¡ã¿ããã°ã©ãã³ã°ã®ä¸çã¸ããããï¼ããã®ã§ãããC++20ã§ããã°std::string
ãã³ã³ãã¤ã«æã«ä½¿ç¨ã§ããã®ã§ããããããã«ã¯ãªãã¾ãã
#include <ranges> #include <print> #include <string> template<std::size_t N> consteval auto make_format_string_for_pack() { std::string fmtstr = ""; // ããªãã¿ã¯ã好ã¿ã§ constexpr std::string_view append = "{}, "; for (auto _ : std::views::iota(0ull, N)) { fmtstr += append; } std::array<char, append.length() * N + 1> save; std::ranges::copy(fmtstr, save.begin()); save.back() = '\0'; return save; } void print_pack(auto&&... args) { static constexpr auto fmtstr_array = make_format_string_for_pack<sizeof...(args)>(); std::print(fmtstr_array.data(), args...); } int main() { print_pack(1, "str", 3.1415, 'c', true); }
1, str, 3.1415, c, true,
ããã§ããããã§ãããæ¸ããã¨ãå¤ãããããªããã¯ãã«ã«ãªé¨åãå¤ãã³ã¼ãã«ãªã£ã¦ãã¾ãããªãããããstd::array
ã«è©°ããªããã¦ããã®ãï¼ãªãstatic constexpr
ï¼ï¼ãªã©ãªã©ã
å®è¡æãã©ã¼ãããã使ã
ç´ ç´ã«å®è¡æã«ããæ¹æ³ã§ãã
#include <ranges> #include <print> #include <string> void print_pack(auto&&... args) { std::string fmtstr = ""; for (auto _ : std::views::iota(0ull, sizeof...(args))) { // ããªãã¿ã¯ã好ã¿ã§ fmtstr += "{}, "; } std::vprint_unicode(fmtstr, {std::make_format_args(args...)}); } int main() { print_pack(1, "str", 3.1415, 'c', true); }
1, str, 3.1415, c, true,
è¨è¿°éèªä½ã¯æ¸ãã¾ãããå®è£ ãåç´ã«ãªãã¾ãããããããã®å ´åããã©ã¼ãããæååã®ãã§ãã¯ãã³ã³ãã¤ã«æã«è¡ãããªããªããããä¾ãã°ããã¯ã®ä¸ã«ãã©ã¼ãããã§ããªãåãå«ã¾ãã¦ãã¦ãå®è¡æã¨ã©ã¼ã«ãªãã¾ãã
std::tie()
å¤æ¥ããããã©ã¡ã¼ã¿ããã¯ãæ±ãéã«ã¯std::tuple
ã¨ãã®å¨è¾ºã¦ã¼ãã£ãªãã£ã便å©ã«æ´»ç¨ã§ãããã¨ãè¯ãç¥ããã¦ãã¾ããããã¦ãC++23ããã¯std::tuple
ã®ãã©ã¼ããããµãã¼ããå
¥ããããstd::tuple
ã¯ãã®ã¾ã¾ãã©ã¼ãããå¯è½ã«ãªãã¾ãã
ãããã£ã¦ãtuple
ï¼std::tie()
ï¼ãå©ç¨ãããã¨ã§ä¸çªã·ã³ãã«ã«æ¸ããã¨ãã§ãã¾ãã
#include <ranges> #include <print> #include <string> void print_pack(auto&&... args) { std::print("{}", std::tie(args...)); } int main() { print_pack(1, "str", 3.1415, 'c', true); }
(1, "str\u{0}", 3.1415, 'c', true)
æåååºåãã¨ã¹ã±ã¼ãããã¦ããã®ã¯ãã¶ãclangã®å®è£ ãã°ã§ããæ¬æ¥ã¨ã¹ã±ã¼ããããªãã®ãæ£ããã¯ãã
ä¸çªçããã¤åç´ã§ãããªããããã®æ¹æ³ã§ããã°éããã¯å¼æ°ã¨çµã¿åããããã¨ãã§ãããstd::tuple
ç¨ã®ãã©ã¼ããããªãã·ã§ã³ã使ç¨ãããã¨ãã§ãã¾ãã
ãã ããstd::tuple
ã®ãã©ã¼ããããµãã¼ããC++23ãããªã®ã§ãC++20ã®std::format()
ã§ã¯ãã®æ¹æ³ã¯ä½¿ãã¾ãããåã®2ã¤ã®ã©ã¡ããã§é å¼µãã¾ãããã
ãªããstd::tie(args...)
ã§ã¯ãªãstd::tuple(args...)
ã使ç¨ãã¦ãåããã¨ã¯éæã§ãã¾ãããtuple
ãç´æ¥æ§ç¯ãã¦ãã¾ãã¨åè¦ç´ ãã³ãã¼ãããã®ã§æ³¨æãå¿
è¦ã§ãã
std::tuple
ã®ãã©ã¼ããããªãã·ã§ã³
std::tie()
ã«ããæ¹æ³ã§ããã°ãéå®çãªãã®ã§ã¯ãããã®ã®std::tuple
ã®ããã®ãã©ã¼ããããªãã·ã§ã³ã使ç¨ãããã¨ãã§ãã¾ãã
ã¾ããn
ãªãã·ã§ã³ã«ãã£ã¦å²ã¿æåï¼()
ï¼ãçããã¨ãã§ãã¾ãã
void print_pack(auto&&... args) { std::println("{:n}", std::tie(args...)); std::println("{{{:n}}}", std::tie(args...)); }
1, "str\u{0}", 3.1415, 'c', true {1, "str\u{0}", 3.1415, 'c', true}
std::tuple
åºæã®ãªãã·ã§ã³ã¯ãããããã§ãæ®ãã¯æ´æ°åçä»ã®åã¨åããå¹
æå®ã«é¢ãããªãã·ã§ã³ã使ç¨ã§ãã¾ãã
void print_pack(auto&&... args) { std::println("|{:*<40n}|", std::tie(args...)); std::println("|{:+>40n}|", std::tie(args...)); std::println("|{:-^40n}|", std::tie(args...)); }
|1, "str\u{0}", 3.1415, 'c', true********| |++++++++1, "str\u{0}", 3.1415, 'c', true| |----1, "str\u{0}", 3.1415, 'c', true----|
å¹
ã¨å¯ããåãæåã®ãªãã·ã§ã³æå®ã¯tuple
ã®è¦ç´ åæ¯ã§ã¯ãªãtuple
ã®å
¨ä½ã«é©ç¨ããã¾ãã