如何用C++ Concepts实现std::decay等效的类型约束?
用C++ Concepts实现基于std::decay的类型匹配限制
标准库确实没有直接对应std::decay的预定义Concept,但我们可以通过组合现有工具轻松实现你的需求,替代原来的std::enable_if写法。
方式一:直接在模板中使用约束
直接在函数模板的requires子句中组合std::decay_t和std::same_as,逻辑和原代码完全一致,但写法更直观:
#include <type_traits> #include <concepts> template <typename T> struct some_struct { template <typename U> requires std::same_as<std::decay_t<U>, T> void do_something(U obj) { return; } }; int main() { some_struct<int> obj; obj.do_something(0); // 编译通过 // obj.do_something("test"); // 编译错误:decay后是const char*,与int不匹配 }
方式二:自定义可复用的Concept
如果需要在多处复用“类型衰减后匹配目标类型”的逻辑,可以自定义一个Concept封装该规则:
#include <type_traits> #include <concepts> // 自定义Concept:From类型经过decay后与To类型相同 template <typename From, typename To> concept DecaysTo = std::same_as<std::decay_t<From>, To>; template <typename T> struct some_struct { // 直接用自定义Concept约束U template <DecaysTo<T> U> void do_something(U obj) { return; } }; int main() { some_struct<int> obj; obj.do_something(0); // 编译通过 obj.do_something(static_cast<const int&>(0)); // 编译通过:引用衰减后仍是int // obj.do_something(3.14); // 编译错误:double衰减后仍与int不匹配 }
优势说明
这两种实现都等价于你原来的std::enable_if代码,但Concept写法的优势在于:
- 代码可读性更强,约束逻辑直接暴露在模板参数或函数声明处
- 编译错误信息更友好,编译器会明确指出参数不符合
DecaysTo<T>或std::same_as<std::decay_t<U>, T>的约束,而非enable_if那种模糊的“候选函数不可行”提示
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

