如何强制C++泛型类仅接受非指针标量及合规结构体?
解决方案
要实现泛型类仅接受指定类型的需求,我们需要分两类判断目标类型是否合规:一是非指针的标量类型,二是仅包含非指针标量成员的结构体/聚合类。以下是具体实现方案:
1. 基础类型判断:非指针标量
首先定义辅助常量,用来快速判断类型是否属于允许的标量范畴:
#include <type_traits> template <typename T> constexpr bool is_allowed_scalar = std::is_scalar_v<T> && !std::is_pointer_v<T>;
这里利用std::is_scalar判断标量类型,再通过!std::is_pointer排除指针类型。
2. 结构体类型判断:成员均为合规标量
由于标准C++没有内置的结构体成员遍历能力,提供两种实现方式:
方式一:使用Boost.PFR(推荐,无需手动维护成员)
Boost.PFR是轻量级编译期工具库,可直接获取聚合类型的成员信息,无需依赖C++反射特性:
#include <boost/pfr.hpp> template <typename T> constexpr bool is_allowed_struct = std::is_aggregate_v<T> && !std::is_scalar_v<T> && []<std::size_t... Is>(std::index_sequence<Is...>) { return (is_allowed_scalar<boost::pfr::tuple_element_t<Is, T>> && ...); }(std::make_index_sequence<boost::pfr::tuple_size_v<T>>{});
此方案会自动遍历结构体所有成员,检查每个成员是否为合规的非指针标量。
方式二:纯标准库实现(需手动特化结构体)
若无法引入第三方库,需为每个合规结构体手动特化判断模板:
// 前置声明判断模板 template <typename T> constexpr bool is_allowed_struct = false; // 示例:为自定义结构体特化判断逻辑 struct MyStruct { int id; double value; char flag; }; template <> constexpr bool is_allowed_struct<MyStruct> = true;
3. 模板类中的static_assert条件
将两类判断逻辑结合,放入模板类的编译期断言中:
template <typename T> class C { static_assert(is_allowed_scalar<T> || is_allowed_struct<T>, "类型必须是非指针标量,或仅包含非指针标量成员的结构体"); // ... 类成员与方法实现 };
补充说明
- 合规标量类型包含:算术类型(int、double等)、枚举类型、
std::nullptr_t - 结构体需满足聚合类型要求(无用户定义构造函数、无虚函数等),才能被Boost.PFR正确识别
内容的提问来源于stack exchange,提问作者zdf
相关产品推荐
相关产品推荐

