如何通过static_assert校验函数返回值为弱序可比较类型?
C++20 最简实现方案
如果你的编译环境支持C++20,直接用requires约束即可,完全不需要依赖返回类型的默认构造能力,检测逻辑和实际代码执行逻辑完全一致:
#include <type_traits> // 直接把约束写到模板声明上,编译期自动校验 template <typename TFunc> requires requires(TFunc f, double x, double y) { // 校验f(x) < f(y)表达式合法,且返回值可转换为bool { f(x) < f(y) } -> std::convertible_to<bool>; } void func(TFunc f) { double x{1}, y{2}; bool z = f(x) < f(y); }
如果你需要单独写static_assert也可以把requires表达式放到断言里:
static_assert(requires(TFunc f, double x) { { f(x) < f(x) } -> std::convertible_to<bool>; }, "Function f must return a type that supports operator< comparison.");
兼容C11/C17 实现方案
如果用不了C++20的requires语法,可以用std::declval配合类型萃取实现检测,std::declval是专门用于编译期未求值上下文的工具,不需要类型真的支持构造:
#include <type_traits> // 定义类型萃取:检测T是否支持operator<且返回值可转bool template <typename T, typename = void> struct has_less_operator : std::false_type {}; template <typename T> struct has_less_operator<T, std::void_t<decltype(std::declval<T>() < std::declval<T>())>> : std::is_convertible<decltype(std::declval<T>() < std::declval<T>()), bool> {}; template <typename T> constexpr bool has_less_operator_v = has_less_operator<T>::value; // 业务函数实现 template <typename TFunc> void func(TFunc f) { // 先推导f接收double参数的返回值类型,不需要实际构造对象 using RetType = decltype(f(std::declval<double>())); static_assert(has_less_operator_v<RetType>, "Function f must return a weakly ordered type supporting operator<."); double x{1}, y{2}; bool z = f(x) < f(y); }
以上两种方案都不会对返回类型有额外的默认构造、拷贝构造要求,检测逻辑严格匹配实际代码的比较逻辑,不会出现校验通过但实际编译失败的问题。
内容的提问来源于stack exchange,提问作者SMeznaric
相关产品推荐
相关产品推荐

