You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何检测类重载+运算符时,C、D类型的判断结果为false?

为什么检测C和D的operator+重载返回false?

先看你写的检测模板:

template <typename T, typename = void>
struct has_p_op : std::false_type {};

template <typename T>
struct has_p_op<T, decltype(std::declval<T>() + std::declval<T>())> : std::true_type {};

核心问题是模板特化的第二个参数类型不匹配:

  • 默认模板的第二个参数默认值是void,只有当特化版本的第二个参数类型也是void时,才会触发特化,返回true_type。
  • 对于B的operator+,返回值是void,所以declval<B>() + declval<B>()的类型是void,特化的第二个参数刚好是void,匹配成功,结果为true。
  • 对于C的operator+,返回值是C,特化的第二个参数类型变成了C,和默认的void不匹配,所以不会触发特化,使用默认的false_type。
  • 对于D的operator+,返回值是D&,特化的第二个参数类型是D&,同样和void不匹配,结果自然是false。

解决方法

只需要让特化版本的第二个参数始终为void,不管operator+返回什么类型,有两种实现方式:

方式1:C++17及以上用std::void_t

需要引入<type_traits>头文件:

#include <type_traits>

template <typename T, typename = void>
struct has_p_op : std::false_type {};

template <typename T>
struct has_p_op<T, std::void_t<decltype(std::declval<T>() + std::declval<T>())>> : std::true_type {};

方式2:兼容C++11及以上的void转换

对表达式做强制void转换,忽略返回值类型:

template <typename T, typename = void>
struct has_p_op : std::false_type {};

template <typename T>
struct has_p_op<T, decltype((void)(std::declval<T>() + std::declval<T>()))> : std::true_type {};

修改后,C和D的检测结果都会变为true,因为特化的第二个参数始终是void,和默认模板的参数匹配,触发特化逻辑。

内容的提问来源于stack exchange,提问作者deponovo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 04:16:43