在 std::ostream 输出后添加一个新行而不显式调用它
Adding a new line after std::ostream output without explicitly calling it
下面的例子最能说明我的问题:
class Stream
{
public:
Stream(std::ostream& os)
:
stream(os)
{
}
auto getStream()
{
return std::pair<std::ostream&, std::unique_ptr<StreamDelegate>>(stream, std::make_unique<StreamDelegate>(stream));
}
private:
std::ostream& stream;
};
int main()
{
Stream os(std::cout);
os.getStream() << "input1" << "input2";
//execute some code without explicitly calling it
//such os.getStream() << std::endl;
}
我(工作)尝试实现此功能:
class StreamDelegate
{
public:
StreamDelegate(std::ostream& os)
:
stream(os)
{
}
~StreamDelegate()
{
//some delegated functionality
//exmpl:
stream << std::endl;
}
private:
std::ostream& stream;
};
class Stream
{
public:
Stream(std::ostream& os)
:
stream(os)
{
}
auto getStream()
{
return std::pair<std::ostream&, std::unique_ptr<StreamDelegate>>(stream, std::make_unique<StreamDelegate>(stream));
}
private:
std::ostream& stream;
};
int main()
{
Stream os(std::cout);
os.getStream().first << "input1" << " input2";
os.getStream().first << "line2: input1" << " line2: input 2";
std::cin.get();
}
是否有其他更优雅的方法来实现此功能?
此外,我发现我的代码中可能存在缺陷。如下代码所示:
int main()
{
Stream os(std::cout);
auto pitfall = os.getStream();
pitfall.first << "line1";
pitfall.first << "should be line 2";
std::cin.get();
}
由于 os.getStream()
的 return 值被分配给一个变量,StreamDelegate
没有被破坏,因此没有期望的行为。
我不打算将 Stream::getStream()
分配给一个变量,但如果有办法解决这个问题,我想知道。
我也知道我可以通过以与 StreanDelegate
相同的方式实现 Stream
析构函数来避免 StreamDelegate
,但我可能希望它在单例上工作.
我认为你使用 RAII 的想法很好。如果你为你的 Stream
实现模板化 operator<<
并且让 return 你的 StreamDelegate
它变得更容易使用,并且更难通过分配给变量来破坏破坏。
#include <iostream>
class StreamDelegate
{
public:
StreamDelegate(std::ostream& os) : stream(os) {}
~StreamDelegate() {
//some delegated functionality
//exmpl:
stream << std::endl;
}
template <typename T>
StreamDelegate& operator<<(T&& val) {
stream << std::forward<T>(val);
return *this;
}
StreamDelegate& operator=(const StreamDelegate&) = delete;
StreamDelegate(const StreamDelegate&) = delete;
private:
std::ostream& stream;
};
class Stream
{
public:
Stream(std::ostream& os) : stream(os) {}
template <typename T>
StreamDelegate operator<<(T&& val) {
stream << std::forward<T>(val);
return StreamDelegate(stream);
}
private:
std::ostream& stream;
};
int main()
{
Stream os(std::cout);
os << "input1" << " input2";
os << "line2: input1" << " line2: input 2";
std::cin.get();
}
编辑
我为 StreamDelegate
明确声明 copy-constructor 和 copy-assignment 为删除,所以不再可能
auto delegate = os << "input3";
下面的例子最能说明我的问题:
class Stream
{
public:
Stream(std::ostream& os)
:
stream(os)
{
}
auto getStream()
{
return std::pair<std::ostream&, std::unique_ptr<StreamDelegate>>(stream, std::make_unique<StreamDelegate>(stream));
}
private:
std::ostream& stream;
};
int main()
{
Stream os(std::cout);
os.getStream() << "input1" << "input2";
//execute some code without explicitly calling it
//such os.getStream() << std::endl;
}
我(工作)尝试实现此功能:
class StreamDelegate
{
public:
StreamDelegate(std::ostream& os)
:
stream(os)
{
}
~StreamDelegate()
{
//some delegated functionality
//exmpl:
stream << std::endl;
}
private:
std::ostream& stream;
};
class Stream
{
public:
Stream(std::ostream& os)
:
stream(os)
{
}
auto getStream()
{
return std::pair<std::ostream&, std::unique_ptr<StreamDelegate>>(stream, std::make_unique<StreamDelegate>(stream));
}
private:
std::ostream& stream;
};
int main()
{
Stream os(std::cout);
os.getStream().first << "input1" << " input2";
os.getStream().first << "line2: input1" << " line2: input 2";
std::cin.get();
}
是否有其他更优雅的方法来实现此功能?
此外,我发现我的代码中可能存在缺陷。如下代码所示:
int main()
{
Stream os(std::cout);
auto pitfall = os.getStream();
pitfall.first << "line1";
pitfall.first << "should be line 2";
std::cin.get();
}
由于 os.getStream()
的 return 值被分配给一个变量,StreamDelegate
没有被破坏,因此没有期望的行为。
我不打算将 Stream::getStream()
分配给一个变量,但如果有办法解决这个问题,我想知道。
我也知道我可以通过以与 StreanDelegate
相同的方式实现 Stream
析构函数来避免 StreamDelegate
,但我可能希望它在单例上工作.
我认为你使用 RAII 的想法很好。如果你为你的 Stream
实现模板化 operator<<
并且让 return 你的 StreamDelegate
它变得更容易使用,并且更难通过分配给变量来破坏破坏。
#include <iostream>
class StreamDelegate
{
public:
StreamDelegate(std::ostream& os) : stream(os) {}
~StreamDelegate() {
//some delegated functionality
//exmpl:
stream << std::endl;
}
template <typename T>
StreamDelegate& operator<<(T&& val) {
stream << std::forward<T>(val);
return *this;
}
StreamDelegate& operator=(const StreamDelegate&) = delete;
StreamDelegate(const StreamDelegate&) = delete;
private:
std::ostream& stream;
};
class Stream
{
public:
Stream(std::ostream& os) : stream(os) {}
template <typename T>
StreamDelegate operator<<(T&& val) {
stream << std::forward<T>(val);
return StreamDelegate(stream);
}
private:
std::ostream& stream;
};
int main()
{
Stream os(std::cout);
os << "input1" << " input2";
os << "line2: input1" << " line2: input 2";
std::cin.get();
}
编辑
我为 StreamDelegate
明确声明 copy-constructor 和 copy-assignment 为删除,所以不再可能
auto delegate = os << "input3";