为何在C++ Concept中使用std::bitset的constexpr size()会失败?
关于Concept中使用
std::bitset::size()的问题分析与解决 问题描述
以下代码可以正常编译,因为foo.size()是constexpr函数,能在编译期返回std::bitset<24>的大小:
std::bitset<24> foo; static_assert(std::same_as<std::bitset<24>, std::bitset<foo.size()>>);
但下面的Concept定义却无法通过断言:
template <typename T> concept is_std_bitset = requires( T t ) { requires std::same_as<T,std::bitset<t.size()>>; }; static_assert(is_std_bitset<std::bitset<24>>); // 断言失败
原因分析
这不是Concept的通用限制,而是Concept的requires表达式中,占位符变量t是抽象的类型实例代表,并非具体的编译期对象。尽管std::bitset::size()是constexpr成员函数,但在这个上下文里,编译器无法从抽象的t中提取出编译期常量值——因为t没有被实例化为具体的对象,也就无法触发size()的constexpr求值来作为std::bitset的模板参数。
解决办法
针对std::bitset的特性,有两种可行的解决方式:
方法1:通过类型 trait 提取std::bitset的模板参数
先定义一个类型 trait 来获取std::bitset<N>中的模板参数N:
#include <bitset> #include <concepts> template<typename T> struct bitset_size; template<std::size_t N> struct bitset_size<std::bitset<N>> : std::integral_constant<std::size_t, N> {}; template<typename T> inline constexpr std::size_t bitset_size_v = bitset_size<T>::value;
再基于这个trait定义Concept:
template <typename T> concept is_std_bitset = requires { requires std::same_as<T, std::bitset<bitset_size_v<T>>>; };
方法2:直接特化Concept匹配std::bitset模板
更简洁的方式是直接对std::bitset<N>特化Concept:
#include <bitset> #include <concepts> template<typename T> concept is_std_bitset = false; template<std::size_t N> concept is_std_bitset<std::bitset<N>> = true;
两种方法都能让static_assert(is_std_bitset<std::bitset<24>>)正常通过编译。
内容的提问来源于stack exchange,提问作者goneskiing
相关产品推荐
相关产品推荐

