【问题标题】:Overload operator<< for arrays数组的重载运算符<<
【发布时间】:2012-03-14 08:38:58
【问题描述】:

我想为任意数组重载operator&lt;&lt;,这样代码cout &lt;&lt; my_arr 就可以工作。首先我尝试在const T (&amp;arr)[N] 上重载operator&lt;&lt; 的第二个参数,其中TN 是模板参数。但是测试代码发现了一个副作用:const char[] 也匹配类型规范,并且新的重载与流类中定义的重载冲突。示例代码:

#include <cstddef>
#include <iostream>

template<typename T, std::size_t N>
std::ostream& operator<<(std::ostream& os, const T (&arr)[N])
{
    /* do stuff */
    return os;
}

int main()
{
    std::cout << "noooo\n"; /* Fails: ambiguous overload */
}

这样的数组打印算子还能实现吗?

【问题讨论】:

  • 我认为 N 在很多情况下不会很好地转移。 void f(int arr[], size_t N){ cout&lt;&lt;arr; }
  • 如果你想要一个外部库,为什么不直接使用boost.org/doc/libs/1_48_0/doc/html/boost_lexical_cast.html
  • @Captain: arr 在这种情况下实际上具有 int* 类型,因此它与该重载不匹配。
  • @GeorgFritzsche 你是对的。一个简单的测试显示“错误:没有匹配函数调用‘operator

标签: c++ operator-overloading iostream


【解决方案1】:

当然:

template<typename T, std::size_t N>
typename std::enable_if<!std::is_same<T, char>::value, std::ostream&>::type
operator<<(std::ostream& os, const T (&arr)[N])
{
    // ...
}

Tchar 使用SFINAE 时,这将禁用您的过载。

对于 C++03,Boost 有 enable_ifis_same。或者只是自己动手:

template<class T, class U> struct is_same { 
    enum { value = false }; 
};
template<class T> struct is_same<T, T> { 
    enum { value = true }; 
};

template<bool, class T> struct enable_if {};
template<class T> struct enable_if<true, T> { 
    typedef T type; 
};

【讨论】:

  • @Mr.Anubis:改用boost::enable_ifboost::is_same。如果你不想要 Boost,自己实现它们,这两个是微不足道的。
  • @GeorgFritzsche:你是对的。但它应该是吗?我猜const T(&amp;)[] 也可以绑定到一个非常量数组,所以是的,写得很好。更深层次的const 无法隐式添加。
猜你喜欢
  • 2012-02-21
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
  • 2015-09-17
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
  • 1970-01-01
相关资源
最近更新 更多