c++ - 如何编写插入运算符函数模板?

标签 c++ operator-overloading function-templates

我正在尝试为插入运算符编写一个函数模板,而不是一堆类似的重载。冗余的重载版本有效,但是当我尝试将它们组合在一个函数模板中时,编译器提示有歧义。例如:


#include <iostream>
#include <list>

class fooBar
{
public:
    fooBar(int iVal): iValue(iVal) {}
    int getValue() {return iValue;}
    
private:
    int iValue;

};

class foo
{
public:
    foo()
    {
        for(int i = 0; i < 64; i++)
            lstFooBars.push_back(fooBar(i));
    }
    std::list<fooBar>& getList()
    {
        return lstFooBars;
    }

private:
    std::list<fooBar> lstFooBars;
    
};

class bar
{
public:
    bar()
    {
        for(int i = 0; i < 64; i++)
            lstFooBars.push_back(fooBar(i));
    }
    std::list<fooBar>& getList()
    {
        return lstFooBars;
    }

private:
    std::list<fooBar> lstFooBars;
    
};

std::ostream& operator<<(std::ostream& osOut, fooBar& fbrFooBar)
{
    osOut << fbrFooBar.getValue();

    return osOut;
}

template <typename T> std::ostream& operator<<(std::ostream& osOut, T& tContainer)
{
    for(fooBar fbrFooBar: tContainer.getList())
        osOut << "[" << fbrFooBar << "] ";

    return osOut;
}

int main()
{
    foo fooFoo;
    bar barBar;

    std::cout << std::endl << fooFoo << std::endl << std::endl;
    std::cout << std::endl << barBar << std::endl << std::endl;

    return 0;
}

...编译器告诉我:

test.cpp: In function ‘std::ostream& operator<<(std::ostream&, T&)’:
test.cpp:63:9: error: ambiguous overload for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream<char>’} and ‘const char [2]’)
   63 |   osOut << "[" << fbrFooBar << "] ";
      |   ~~~~~ ^~ ~~~
      |   |        |
      |   |        const char [2]
      |   std::ostream {aka std::basic_ostream<char>}

为什么当您针对每种情况一遍又一遍地重载相同的函数时它会起作用并且它不会像这样编译?我在这里缺少什么?

最佳答案

您无意中为 const char* 添加了一个可能的重载:

template<typename T>
std::ostream& operator<<(std::ostream& osOut, T& tContainer)

如果您使用 SFINAE 缩小范围,它应该可以工作。

此重载仅适用于具有 getList() 成员函数的类型,例如:

template<typename T, typename U = decltype(std::declval<T>().getList())>
std::ostream& operator<<(std::ostream& osOut, T& tContainer)

关于c++ - 如何编写插入运算符函数模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65256997/

相关文章:

c++ - 读取文件

c++ - 在通用引用上前进与前进

C++ 运算符混合使用和优先级不是我想要的

c++ - 是否可以调用注入(inject)的 friend 模板函数?

c++ - 关于函数模板的相同代码块在 g++ 下编译正常,但在 VC6 下编译错误,为什么?

c++ - 如何使我的 C++ 代码能够跨平台?

c++ - 在 C++ 中创建一个文件,就像按右键->新建->新建文本文档一样

haskell - 如何在 Haskell 中实现 ^ 运算符?

C++:重载 "pointer to object"* 运算符

node.js - Node : function template without return value