如何使用类型特征/概念来检查一个类型是否可格式化?

5

我想确认某个类型是否可以与 std::format 一起使用。

以下是我的初步尝试:

template<typename Object>
concept formattable = requires(const Object & obj)
{
    std::format("{}", obj);
};

但是这并不起作用。它基本上对所有类型都返回 true。即使是那些不能与 std::format 一起使用的类型。

static_assert(!formattable<std::vector<int>>); // 应该返回 false

为什么它不起作用?

1个回答

10

更新:

随着格式化范围的引入,C++23中已经有一个专门用于测试类型是否可格式化的概念,即std::formattable


由于`std::format`不是一个受限制的函数,表达式`std::format("{}", obj)`始终是合法的。你可能想这样做。
#include <format>
    
template<typename T>
concept formattable = requires (T& v, std::format_context ctx) {
  std::formatter<std::remove_cvref_t<T>>().format(v, ctx);
};

主要基于[format.arg]basic_format_arg构造函数的约束。

演示


你能解释一下为什么需要 std::format_context::template 这行代码吗?我对这种语法不是很熟悉。 - Elad Maimoni
1
访问在std::format_context中定义的模板类型别名@EladMaimoni。 - 康桓瑋
1
@elad template 关键字告诉编译器紧随其后的 formatter_type < std::remove_cvref_t 是所有 T 的模板的一部分,而不是有时候的比较。C++ 语法太疯狂了! - BoP
8
我认为这里不需要使用template,因为std::format_context不是一个相关的名称。 - cpplearner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接