如何使用我自己的模板功能将std ::格式化()包装?

发布于 2025-02-11 07:58:02 字数 1337 浏览 2 评论 0 原文

注意:此问题使用C ++ 20,我正在使用Visual Studio 2022(V17.2.2)。

我想创建一个模板功能包装器,以允许我使用std ::格式样式记录。包装器功能最终将执行其他一些与此相关的非格式功能,这些内容在这里并不重要。

请参阅下面的代码。请注意, log1()效果很好,但使用笨拙。 log2()还可以,但是使用 std :: vformat()丢失对日志格式字符串的编译时间检查。

我真正想做的是 log3()。问题是Visual Studio(V17.2.2)不喜欢这样。

有什么办法可以使它起作用(没有宏)?

#include <iostream>
#include <format>
#include <string_view>
 
// works fine:  usage is clunky
auto Log1(std::string_view sv)
{
    std::cout << sv;
}
 
// works, but fmt string is checked at runtime - not compile time
template<typename... Args>
auto Log2(std::string_view fmt, Args&&... args)
{
    std::cout << std::vformat(fmt, std::make_format_args(args...));
}
 
// this doesn't work
template<typename... Args>
auto Log3(std::string_view fmt, Args&&... args)
{
    std::cout << std::format(fmt, std::forward<Args>(args)...);
}
 
int main()
{
    Log1(std::format("Hello, {}\n", "world!")); // ok - clunky
    Log2("Hello, {}\n", "world!");              // ok - no compile time checking of fmt string
    Log2("Hello, {:s}\n", 42);                  // ok - throws at runtime
    Log3("Hello, {}\n", "world!");              // ERROR:  doesn't compile
    return 0;
}

Note: this question uses C++20, and I'm using Visual Studio 2022 (v17.2.2).

I would like to create a template function wrapper to allow me to use std::format style logging. The wrapper function will eventually do some other non-format related stuff that is not important here.

Refer to the code below. Note that Log1() works fine, but feels clunky to use. Log2() is ok, but using std::vformat() loses compile-time checking of log format strings.

What I really want to do is Log3(). Problem is that Visual Studio (v17.2.2) doesn't like this.

Is there any way I can get this to work (without macros)?

#include <iostream>
#include <format>
#include <string_view>
 
// works fine:  usage is clunky
auto Log1(std::string_view sv)
{
    std::cout << sv;
}
 
// works, but fmt string is checked at runtime - not compile time
template<typename... Args>
auto Log2(std::string_view fmt, Args&&... args)
{
    std::cout << std::vformat(fmt, std::make_format_args(args...));
}
 
// this doesn't work
template<typename... Args>
auto Log3(std::string_view fmt, Args&&... args)
{
    std::cout << std::format(fmt, std::forward<Args>(args)...);
}
 
int main()
{
    Log1(std::format("Hello, {}\n", "world!")); // ok - clunky
    Log2("Hello, {}\n", "world!");              // ok - no compile time checking of fmt string
    Log2("Hello, {:s}\n", 42);                  // ok - throws at runtime
    Log3("Hello, {}\n", "world!");              // ERROR:  doesn't compile
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谁把谁当真 2025-02-18 07:58:02

您需要 std :: Basic-Format-rt;图表,Args ...&gt; ,它允许您写作:

template<typename... Args>
auto Log3(std::format_string<Args...> fmt, Args&&... args)

直到那时,您只能是顽皮并使用MSVC实现的内部助手,并了解他们可以随时随地重命名此类类型。

template<typename... Args>
auto Log3(std::_Fmt_string<Args...> fmt, Args&&... args) 

You need P2508 (my paper) to land, which exposes the currently exposition-only type std::basic-format-string<charT, Args...>, which will allow you to write:

template<typename... Args>
auto Log3(std::format_string<Args...> fmt, Args&&... args)

Until then, you can just be naughty and use the MSVC implementation's internal helper for this, with understanding that they can rename this type at will at any point.

template<typename... Args>
auto Log3(std::_Fmt_string<Args...> fmt, Args&&... args) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文