c++ - 在模板函数中包装 std::format 无法使用最新的 MSVC 编译器更新进行编译

我对为什么这段代码突然停止编译感到有些困惑:https://godbolt.org/z/hhM5GG78x

但是如果我将编译器改回 v19.31,它将编译:https://godbolt.org/z/11j8WbEzG

这是有问题的代码:

#include <format>
#include <string>

template <typename... Args>
void FormatString(const std::string_view& fmt_str, Args&&... args)
{
    puts(std::format(fmt_str, args...).c_str());
}

int main()
{
    FormatString("This is a {}.\n", "test");
    return 0;
}

这是我收到的错误消息:

<source>(7): error C7595: 'std::_Basic_format_string<char,const char (&)[5]>::_Basic_format_string': call to immediate function is not a constant expression
<source>(7): note: failure was caused by a read of a variable outside its lifetime
<source>(7): note: see usage of 'fmt_str'
<source>(12): note: see reference to function template instantiation 'void FormatString<const char(&)[5]>(const std::string_view &,const char (&)[5])' being compiled

它抱怨 fmt_str 在它的生命周期之外被使用。我没有看到这是怎么回事?

回答1

std::format 的第一个参数必须在编译时知道,因为 format 字符串被指定为只能构造为常量表达式。目的是保证无效 format 字符串的编译时错误。

fmt_str 是一个函数参数,因此它的 value 绝不是编译时常量。

您可以改用 https://en.cppreference.com/w/cpp/utility/format/vformat ,但它不会对 format 字符串执行编译时检查,而是将其延迟到运行时(出错时抛出 std::format_error ):

puts(std::vformat(fmt_str, std::make_format_args(args...)).c_str());

如果您不需要 fmt_str 依赖于运行时,则可以将其作为模板参数传递。不幸的是,目前这并不是那么直接,因为 std::stringstd::string_view 不能用于此,并且字符串文字不能直接通过 const char* 非类型模板参数传递。

因此,您可能希望创建自己的结构固定长度字符串类型,可用作非类型模板参数,例如这里是用例的一个非常小的版本,您可能希望根据需要对其进行扩展:

template<std::size_t N>
struct fixed_string {
    char str[N];
    constexpr fixed_string(const char (&str_)[N]) noexcept {
        std::ranges::copy(str_, str);
    }
};

template <fixed_string fmt_str, typename... Args>
void FormatString(Args&&... args)
{
    puts(std::format(fmt_str.str, args...).c_str());
}

int main()
{
    FormatString<"This is a {}.\n">("test");
    return 0;
}

我假设 MSVC 根本还没有实现 std::format 的第一个参数在以前的版本中可以构造为常量表达式的要求。

该要求是在 C++20 之后为 C++23 添加的,但如果理解正确,也可以追溯适用于 C++20 作为缺陷报告,通过 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2216r3.html 论文中列出的投票包含相关更改。

相似文章

随机推荐

最新文章