定义 ostream 运算符<<用于类中定义的 typedef

Defining ostream operator<< for typedef defined in the class

本文关键字:lt 定义 typedef ostream 用于 运算符      更新时间:2023-10-16

谁能给我一个提示,如何在提供的代码示例中为 MyType 正确实现运算符<<?

#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;
}

上面的代码无法编译。但是当我更改运算符的定义<<注释掉一个时,一切正常。这只是一个(不是)更复杂问题的工作示例,实际上MyType要讨厌得多。在这个简单的例子中,我可以轻松地从"A"类复制粘贴MyType的确切定义,但在更复杂的情况下,当这个typedef依赖于antoher typedef时......只是参考它会很好。这个问题有什么解决方案吗?

编辑:

编译器的输出错误(通常好像运算符<<根本没有定义,因此当运算符的两个定义<<从示例中注释掉编译器打印相同的错误时)。

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;}
~~~~~~~~~ ^  ~~~~

问题是非推导的上下文(感谢 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 来说效果很好,如果它适用于你更复杂的类——不知道更多细节就不可能说......

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

#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<char>}' lvalue to 'std::basic_ostream<char>&&'

此错误通常意味着类型推导无法正常工作(不可扣除上下文)(请参阅为什么模板类型推导不起作用和 ostream 左值错误)

因此,我认为,目前,你应该找到另一种方法来解决这个问题,这种方式我暂时想不出来。