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

如何检测C++类是否定义operator<<?为何检测结果均为0?

问题:为何检测全局operator<<的type traits返回false?

我想用type traits检测类是否定义了operator<<运算符,定义了结构相似的类A和B,只为A重载了全局的operator<<。用boost::is_detected实现检测逻辑,但运行后A和B的检测结果都为false。

代码如下:

#include<iostream>
#include <boost/type_traits/is_detected.hpp>
class A
{
  public:
    std::string name;
    int64_t age;
    bool b;

};

class B
{
  public:
    std::string name;
    int64_t age;
    bool b;

};

std::ostream& operator<<(std::ostream& destination, const A& type)
{
    return destination << "name=" << type.name << ", age=" << int(type.age)<<std::endl;
}


template <typename T>
using has_operator_insertion_check = decltype(void(&std::decay_t<T>::operator<<));

template <typename T>
using has_operator_insertion = boost::is_detected<has_operator_insertion_check, T>;

template <typename T>
constexpr bool has_operator_insertion_v = has_operator_insertion<T>::value;


int main()
{
  A a, b;
  a.name = "Ciaooooo";
  a.age = 65536;
  a.b = true;
  std::cout<<"A has operator '<<'? "<<has_operator_insertion_v<A><<std::endl;
  std::cout<<"B has operator '<<'? "<<has_operator_insertion_v<B><<std::endl;

  return 0;
}

运行输出:

A has operator '<<'? 0
B has operator '<<'? 0

解答

你的检测逻辑完全错误:

  • 你写的has_operator_insertion_check是在检查类的成员函数operator<<,但你给A定义的是全局非成员版本的operator<<,所以这个检测永远不会命中。
  • 不管是A还是B,都没有定义成员版的operator<<,所以检测结果自然都是false。

正确的检测方式应该模拟std::ostream << T这个表达式是否合法,修改检测模板如下:

// 正确的检测表达式:模拟std::cout << T对象的操作
template <typename T>
using has_operator_insertion_check = decltype(std::declval<std::ostream&>() << std::declval<const T&>());

template <typename T>
using has_operator_insertion = boost::is_detected<has_operator_insertion_check, T>;

template <typename T>
constexpr bool has_operator_insertion_v = has_operator_insertion<T>::value;

修改后运行,就能得到正确结果:

A has operator '<<'? 1
B has operator '<<'? 0

原理说明:

  • std::declval<std::ostream&>()用来获取一个std::ostream的左值引用,不需要实际创建对象。
  • std::declval<const T&>()获取const T的左值引用,匹配你定义的全局operator<<的参数类型。
  • 整个decltype表达式会检查ostream& << const T&是否合法,合法则检测为true,否则为false。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 17:07:42