你真正想要做的是:
std::string sep = " ";
std::string end = "\n";
(std::cout << ... << (sep << args)) << end;
,因爲你想(sep << args)
與std::cout
左摺疊。這是行不通的,因爲sep << args
不知道它正在流入std::cout
或者流式傳輸; <<
只在流媒體的左邊是流。
總之,問題是sep << args
不明白它是流媒體。
您的其他問題是不夠lambda。
我們可以解決這個問題。
template<class F>
struct ostreamer_t {
F f;
friend std::ostream& operator<<(std::ostream& os, ostreamer_t&& self) {
self.f(os);
return os;
}
template<class T>
friend auto operator<<(ostreamer_t self, T&& t) {
auto f = [g = std::move(self.f), &t](auto&& os)mutable {
std::move(g)(os);
os << t;
};
return ostreamer_t<decltype(f)>{std::move(f)};
}
};
struct do_nothing_t {
template<class...Args>
void operator()(Args&&...)const {}
};
const ostreamer_t<do_nothing_t> ostreamer{{}};
template <typename... Args>
void print(Args... args)
{
std::string sep = " ";
std::string end = "\n";
(std::cout << ... << (ostreamer << sep << args)) << end;
}
live example。 (我也用sep
的文字來確保我用rvalues工作)。
ostreamer
捕獲對事物的引用,它是<<
'd,然後將它們轉儲到<<
到ostream
。
整個過程對於編譯器來說應該是透明的,所以體面的優化器應該會消除所有涉及的事情。
對於'(std :: cout << sep << args,...);'它說「表達式不允許作爲摺疊表達式的操作數」。然而,它表明我把括號放在它的一部分上,比如'((std :: cout << sep << args),...);'但是這會跳過打印第一個參數。有沒有這一行的版本可以工作? – nickeb96
@ nickeb96對,忘了括號。我不確定你對其餘的意思,它不會跳過第一個論點。 – Barry
啊,我得到了第二部分的工作。它打印一個領先的'sep'然而。有沒有一種簡單的方法可以在每個參數之間使用'sep'?還是需要一個更復雜的解決方案,如遞歸? – nickeb96