简体   繁体   English

如何用我自己的模板函数包装 std::format() ?

[英]How can I wrap std::format() with my own template function?

Note: this question uses C++20, and I'm using Visual Studio 2022 (v17.2.2).注意:这个问题使用 C++20,我使用的是 Visual Studio 2022 (v17.2.2)。

I would like to create a template function wrapper to allow me to use std::format style logging.我想创建一个模板函数包装器以允许我使用 std::format 样式日志记录。 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.请注意, Log1()工作正常,但使用起来感觉很笨拙。 Log2() is ok, but using std::vformat() loses compile-time checking of log format strings. Log2 () 没问题,但使用std::vformat()会丢失对日志格式字符串的编译时检查。

What I really want to do is Log3() .我真正想做的是Log3() Problem is that Visual Studio (v17.2.2) doesn't like this.问题是 Visual Studio (v17.2.2) 不喜欢这个。

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;
}

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:您需要P2508 (我的论文)才能着陆,它公开了当前仅用于展示的类型std::basic-format-string<charT, Args...> ,这将允许您编写:

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.在那之前,你可以调皮一点,使用 MSVC 实现的内部帮助器,理解他们可以在任何时候随意重命名这个类型。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 std::ostream 上对我的打印 function 进行模板化? - How can I template my print function on std::ostream? 如何将函数 (std::bind) 包装到命名空间中? - How can I wrap a function (std::bind) into a namespaces? 如何在 clang 格式的函数参数包装和对齐上强加我自己的自定义样式? - How can I impose my own custom style on function parameter wrapping and alignment in clang-format? 如何在 std::function 上使用模板扩展 - How can I use template expansion on a std::function 如何为std :: vector专门化模板成员函数<T> - How can I specialize a template member function for std::vector<T> 如何用另一个模板 function(特别是 glm::dot)包装模板 function? - How can I wrap a template function with another template function (specifically glm::dot)? 我可以将 std::function 的捕获 lambda 放在我自己的 memory 中吗? - Can I place an std::function's capturing lambda in my own memory? 我可以在自己的课上包装升压图吗 - Can I wrap boost graph with my own class 如何在 SWIG 中包装可变参数模板类的可变参数模板成员函数? - How can I wrap a variadic template member function of a variadic template class in SWIG? 如何包装std :: function并轻松访问其返回值和参数类型? - How can I wrap a std::function and have easy access to its return and argument types?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM