将 ostream 包装在类中并模板化<<运算符

Wrap ostream in class and templatize << operator

本文关键字:lt 运算符 包装 ostream      更新时间:2023-10-16

我想将C++流包装在模板类中,以便为流定义的所有<<操作都已可用于包装类。

您能否更改以下代码,使其在不过度更改整体意图的情况下进行编译?

#include <iostream>
class Foo
{
private:
std::ostream& os;
public:
explicit Foo( std::ostream& os ) : os( os ) {};
template<class T>
Foo& operator<<( const T& t )
{
os << t << '!';
return *this;
}
};
int main()
{
Foo( std::cout ) << "test" << 'n'; // works fine 
Foo( std::cout ) << "test" << std::endl; // compilation error
return 0;
}

我假设 std::endl 具有某种类型,因此被模板化方法"捕获"。

正如 kmdreko 所建议的,您需要为模板函数添加重载

(std::endl 是一个模板函数,而不是一个类或简单类型(

喜欢这个:

#include <iostream>
class Foo
{
private:
std::ostream& os;
public:
explicit Foo(std::ostream& os) : os(os) {};
// for classes
template<class T>
Foo& operator<<(const T& t)
{
os << t << '!';
return *this;
}
// for endl
Foo& operator<<(std::ostream& (*pf) (std::ostream&)) {
os << pf;
return *this;
}
};

您可能应该用 SFINAE 保护它并完善参数。

template<class T> auto operator<<(T &&t)
-> decltype(os << std::forward<T>(t) << '!', *this)
{
return os << std::forward<T>(t) << '!', *this;
}

现在,这应该接受std::ostream可以打印并且无法与其他所有内容一起编译的每个参数。