당신이 정말로 원하는 것은 :
std::string sep = " ";
std::string end = "\n";
(std::cout << ... << (sep << args)) << end;
당신이 원하기 때문에 (sep << args)
은 왼쪽 접이식으로 std::cout
입니다. sep << args
이 std::cout
으로 스트리밍되거나 전혀 스트리밍되지 않는다는 것을 모르기 때문에이 방법은 작동하지 않습니다. <<
은 왼쪽이 스트림 인 경우에만 스트리밍됩니다.
간단히 말해서 문제는 sep << args
이 스트리밍 중이라는 것을 이해하지 못한다는 것입니다.
다른 문제는 람다가 아닙니다.
이 문제를 해결할 수 있습니다.
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
에 리터럴을 사용했습니다.)
ostreamer
은 <<
'일 때 참조를 캡처 한 다음 다시 덤프하면 <<
에서 ostream
으로 바뀝니다.
이 전체 프로세스는 컴파일러에게 투명해야하므로 적절한 최적화 프로그램이 모든 것을 증발해야합니다.
'(std :: cout << sep << args, ...);에 대해서는 "표현식이 fold expression의 피연산자로 허용되지 않습니다"라고되어 있습니다. 그러나 그것은'((std :: cout << sep << args), ...);'와 같이 그것의 일부분을 괄호로 묶는 것을 제안하지만 첫 번째 인자를 출력하지 않습니다. 작동 할이 버전의 버전이 있습니까? – nickeb96
@ nickeb96 네, 괄호를 잊어 버렸습니다. 나는 당신이 나머지에 관해 무엇을 의미하는지에 관해 명확히하지 않고있다, 그것은 첫번째 논쟁을 건너 뛰지 않는다. – Barry
아, 두 번째 부분이 작동합니다. 그러나 'sep'를 인쇄합니다. 각각의 인수 사이에'sep '를 갖는 직접적인 방법이 있을까요? 아니면 재귀와 같은보다 복잡한 솔루션이 필요합니까? – nickeb96