【问题标题】:Defining ostream operator<< for typedef defined in the class为类中定义的 typedef 定义 ostream operator<<
【发布时间】:2017-12-10 13:16:45
【问题描述】:

谁能在提供的代码示例中提示我如何正确实现运算符

#include <iostream>
#include <map>


template <typename T>
class A {
public:
    typedef std::map<unsigned int, T> MyType;
    MyType data;

    void show();
};

template <typename T>
std::ostream& operator<<(std::ostream& stream, typename A<T>::MyType const& mm)
{
    return stream << mm.size() << "\n";
}

//template <typename T>
//std::ostream& operator<<(std::ostream& stream, std::map<unsigned int, T> const& mm)
//{
//  return stream << mm.size() << "\n";
//}

template <typename T>
void A<T>::show() {std::cout << data;}

int main() {
    A<double> a;

    a.show();

    return 0;
}

以上代码无法编译。但是,当我将 operator

编辑:

编译器的输出错误(通常好像根本没有定义 operator

g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++14 -MMD -MP -MF"src/ostreamTest.d" -MT"src/ostreamTest.o" -o "src/ostreamTest.o" "../src/ostreamTest.cpp"
../src/ostreamTest.cpp:27:31: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'MyType' (aka 'map<unsigned int, double>'))
    void A<T>::show() {std::cout << data;}
                       ~~~~~~~~~ ^  ~~~~

【问题讨论】:

  • 如果您遇到构建错误,请在问题正文中包含它们(完整、完整且未经编辑)。
  • 我认为 typedef 绑定到它们的范围(我可能错了)。您不能将类中的operator&lt;&lt; 重载为友元成员函数(使用friend 关键字)吗?
  • 另外,我不认为 typedef 适用于不总是相同的类型(template T),在这种情况下我更喜欢using myType = std::map&lt;unsigned int, T&gt;(类型绑定到实例,而不是类)
  • @Vivick:至少在类中这样的定义无济于事:编译器不考虑friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; stream, MyType const&amp; mm) {return stream;}

标签: c++ operator-overloading ostream


【解决方案1】:

所以我正在烹饪这个作为答案

#include <iostream>
#include <map>

template <typename T>
class A{
public:

    using MyType = std::map<unsigned int, T>;
    MyType data;

    void show();

    friend std::ostream& operator<<(std::ostream& stream, const MyType& mm){
        return stream << mm.size() << "\n";
    }
};

template <typename T>
void A<T>::show(){
    std::cout << data;
}

int main()
{
    A<double> a;
    std::cout << a;
    return 0;
}

但是在编译时发生了一个众所周知的构建错误:
error: cannot bind 'std::ostream {aka std::basic_ostream&lt;char&gt;}' lvalue to 'std::basic_ostream&lt;char&gt;&amp;&amp;'

此错误通常意味着类型推导无法正常工作(不可推导上下文)(参见Why is template type deduction not workingostream lvalue error

因此我认为,目前,您应该找到解决此问题的另一种方法,这种方法我暂时想不到。

【讨论】:

    【解决方案2】:

    问题是非推断上下文(感谢 PasserBy 提供链接),这使我们无法找到直接解决方案。

    解决方法可能是将 typedef 移出类,例如:

    template <typename T>
    using A_MyType = std::map<unsigned int, T>;
    
    template <typename T>
    class A
    {
    public:
        typedef A_MyType<T> MyType;
        MyType data;
    
        void show();
    };
    
    template <typename T>
    std::ostream& operator<<(std::ostream& stream, A_MyType<T> const& mm)
    {
        return stream << mm.size() << std::endl;
    }
    

    当然,这适用于 std::map,如果它适用于您更复杂的类 - 不可能在不了解更多细节的情况下说...

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 1970-01-01
      • 2021-04-20
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多