【问题标题】:Overloading output operator for arrays重载数组的输出运算符
【发布时间】:2015-09-17 01:41:11
【问题描述】:

根据this answer,C风格数组重载输出操作符<<的正确方法是这样的——:

#include <iostream>
using namespace std;

template <size_t arrSize>
std::ostream& operator<<( std::ostream& out, const char( &arr )[arrSize] )
{
    return out << static_cast<const char*>( arr ); // use the original version
}

// Print an array
template<typename T1, size_t arrSize>
std::ostream& operator <<( std::ostream& out, const T1( & arr )[arrSize] )
{
    out << "[";
    if ( arrSize )
    {
        const char* separator = "";
        for ( const auto& element : arr )
        {
            out << separator;
            out << element;
            separator = ", ";
        }
    }
    out << "]";
    return out;
}

int main()
{
    int arr[] = {1, 2, 3};
    cout << arr;
}

但我仍然收到编译器错误

error: ambiguous overload for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'const char [2]')  

对于out &lt;&lt; "[";out &lt;&lt; "]"; 语句。

这样做的正确方法是什么?

【问题讨论】:

    标签: c++ arrays templates pretty-print


    【解决方案1】:

    问题是打印字符数组的operator&lt;&lt; 的标准重载是这个:

    template< class CharT, class Traits >
    basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
                                             const char* s );
    

    所以当你提供你的:

    template <size_t arrSize>
    std::ostream& operator<<( std::ostream& out, const char( &arr )[arrSize] )
    

    这将是模棱两可的:我们有两个不同的函数模板具有相同的转换序列,没有一个比另一个更专业。

    但是,由于您希望您的版本只调用原始版本,因此根本没有理由提供您的版本。只需使用 SFINAE 让您的“通用”阵列打印机不接受 char

    // Print an array
    template<typename T1, size_t arrSize, 
             typename = std::enable_if_t<!std::is_same<T1,char>::value>>
    std::ostream& operator <<( std::ostream& out, const T1( & arr )[arrSize] )
    { /* rest as before */ }
    

    【讨论】:

    • 您是否愿意详细说明为什么引用的答案不起作用?是否某些重载消歧规则发生了变化,或者引入了一些东西,或者它从来没有正确?它看起来很奇怪。您的方法也适用于 c++11,如果您将 enable_if_t 换成不太方便的 enable_if,那么我想这将是一种更好的方法,即使对于其他问题也是如此。
    • @luk32 这从来都不是正确的——没有理由偏爱一个重载。
    • 这是我的猜测,尽管我倾向于怀疑自己超过 200k+ 用户接受的答案 =)。感谢您的澄清。
    • @luk32:我当时的声望接近 200 而不是 200k :-(
    • @luk32:我确定了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 2016-01-28
    相关资源
    最近更新 更多