Pét*_*kas 3 c++ c++20 stdformat
我需要在工作中使用std::format这样的上下文:
for(std::size_t i = 0; i < ...; ++i)
{
std::format("some string {}", i);
}
Run Code Online (Sandbox Code Playgroud)
由于循环变量i作为转发引用传递,自动 linter 会发出警告,表明它是通过引用传递的,并且可能会被修改。
在阅读了 cppreference 和std::format 提案后,似乎Formatter要求允许格式化参数为非常量,但我无法弄清楚为什么,并且草案实际上建议const Args&...参数化而不是Args&&...
作为一个实验,我尝试移动字符串,甚至专门std::formatter针对我自己的类型:
#include <format>
#include <iostream>
#include <string>
struct MyStruct {
std::string a = "abc";
MyStruct(){}
MyStruct(const MyStruct&) { std::cout << "copy ctor" << std::endl; }
MyStruct(MyStruct&&) noexcept { std::cout << "move ctor" << std::endl; }
MyStruct& operator=(const MyStruct&) { std::cout << "copy assignment" << std::endl; return *this; }
MyStruct& operator=(MyStruct&&) noexcept { std::cout << "move assignment" << std::endl; return *this; }
};
template <typename CharT>
struct std::formatter<MyStruct, CharT> : std::formatter<std::string, CharT> {
template<typename FormatContext>
auto format(MyStruct id, FormatContext& ctx) const {
return std::formatter<std::string, CharT>::format(id.a, ctx);
}
};
int main()
{
std::string a = std::format("formatted {}", MyStruct{});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
format但即使使用参数而不是 const&进行声明lvalue,也只会调用复制构造函数(std::vformat结果std::make_format_args(MyStruct{})相同)。
所以最后一个问题是,为什么std::format需要转发引用参数,为什么不将它们限制为const&?