Mar*_* He 8 c++ formatting c++20 fmt
我有很多从同一个基类派生的类,并且我试图避免为所有派生类编写格式化程序。我尝试只为基类实现 std::formatter,但将派生类对象/引用传递给 std::format 将触发编译错误。
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include\format(1496): 错误 C2665: 'std::_Format_arg_traits<_Context>::_Phony_basic_format_arg_constructor': 没有5 个重载可以使用 [ _Context=std::format_context ] 转换所有参数类型...
最小代码如下:
#include <format>
#include <iostream>
#include <string>
using namespace std;
struct Base
{
virtual string ToString()
{
return "Base";
}
};
struct D1 : public Base
{
string ToString() override
{
return "D1";
}
};
template <typename CharT> struct ::std::formatter<Base, CharT> : ::std::formatter<::std::string>
{
// parse is inherited from formatter<string>.
template <typename FormatContext> auto format(Base &e, FormatContext &ctx) const
{
::std::string name = e.ToString();
return ::std::formatter<::std::string>::format(name, ctx);
}
};
int main(int argc, char const *argv[])
{
string s;
D1 d;
s = format("{}", d); // this triggers compile errors saying no overloads found
cout << s << endl;
Base &b = d;
s = format("{}", b); // ok after explicit converting to base reference
cout << s << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我假设编译器应该自动转换Derived&
为Base&
,但这并没有发生。实现这一目标的正确方法是什么?
Base
并且D1
是不同的类型。更合适的方法应该是使用约束模板
#include <concepts>
#include <format>
template<std::derived_from<Base> Derived, typename CharT>
struct std::formatter<Derived, CharT> : std::formatter<std::string> {
template<typename FormatContext>
auto format(Derived& e, FormatContext& ctx) const {
std::string name = e.ToString();
return std::formatter<std::string>::format(name, ctx);
}
};
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
627 次 |
最近记录: |