C++ 11 기능을 사용하여 사용자 지정 스트림 조작기를보다 쉽게 만들려고합니다. 람다 함수를 조작자로 사용할 수는 있지만 std::function<ostream&(ostream&)>
은 사용할 수 없습니다.std :: function을 사용자 지정 스트림 조작자로 사용
여기에 코드를 내려 삶은 것 :
g++-4 src/Solve.cpp -c -g -std=c++0x -o src/Solve.o -I/home/ekrohne/minisat
src/Solve.cpp: In function 'int main(int, char**)':
src/Solve.cpp:24:11: error: cannot bind 'std::ostream' lvalue to 'std::basic_ostream<char>&&'
/usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/ostream:579:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = std::function<std::basic_ostream<char>&(std::basic_ostream<char>&)>]'
왜 실패 않습니다
#include <iostream>
#include <functional>
using namespace std;
auto lambdaManip = [] (ostream& stream) -> ostream& {
stream << "Hello world" << endl;
};
function<ostream& (ostream&)> functionManip = [] (ostream& stream) -> ostream& {
stream << "Hello world" << endl;
};
int main (int argc, char** argv) {
cout << lambdaManip; // OK
cout << functionManip; // Compiler error
}
두 번째 cout
문은 다음과 실패? Cygwin gcc 4.5.3을 사용하고 있습니다.
효율성 문제로 인해 어디서나 std::function
을 사용하는 것에 대해 열망하지는 않습니다. 하지만 λ 함수를 반환하는 함수를 작성하고 싶습니다. std::function
없이는 어떻게해야하는지 잘 모릅니다. 예를 들어, 다음과 같은 것은 훌륭 할 것입니다.
auto getAdditionFunctor();
auto getAdditionFunctor() {
return [] (int x, int y) { return x + y };
};
...하지만 분명히 작동하지 않습니다. 작동하는 대체 구문이 있습니까? 나는 그것이 무엇이 될 수 있는지 상상할 수 없다. 그래서 나는 std::function
과 붙어 있을지 모른다.
두 번째 질문에 대한 해결책이 있다면 첫 번째 질문은 논박의 여지가 있습니다.
감사합니다.
정의 operator<<(ostream&, std::function<ostream&(ostream&)>
도움. 나는 웹 페이지를 잘못 읽고, ostream
이 operator()
을 조작자로 가지는 임의의 객체를 처리하기에 충분히 똑똑하다는 인상 아래에있었습니다. 나는 이것에 대해 틀 렸습니다. 게다가, 내가 만든 단순한 lambda
은 아마도 내가 말했던 것처럼 평범한 오래된 함수로 컴파일되었을 것입니다. 실제로 변수 캡처를 사용하여 lambda
이 단순 함수가 아닌지 확인하면 컴파일러가 실패합니다. 또한, 정의 operator()
와 객체는하지 (기본적으로) 매니퓰레이터로 취급됩니다
class Manipulator {
ostream& operator()(ostream& stream) const {
return stream << "Hello world" << endl;
};
} classManip;
function<ostream& (ostream&)> functionManip = [] (ostream& stream) -> ostream& {
return stream << "Hello world" << endl;
};
int main (int argc, char** argv) {
const string str = "Hello world";
auto lambdaManip = [&] (ostream& stream) -> ostream& {
return stream << str << endl;
};
cout << classManip; // Compiler error
cout << lambdaManip; // Compiler error
cout << functionManip; // Compiler error
}
또한 갱신 :
// Tell ostreams to interpret std::function as a
// manipulator, wherever it sees one.
inline ostream& operator<<(
ostream& stream,
const function<ostream& (ostream&)>& manipulator) {
return manipulator(stream);
}
: 그것은으로 수행 할 수 있습니다 아래의 것보다 약간 더 강력한 솔루션을 밝혀
이 코드에는 const
이 여분으로 있습니다. 내 프로젝트에서 실제로이 솔루션을 구현하려고 시도하는 것을 발견했습니다. 당신이 ostream
에 대한 operator<<
보면
해당 조작자에 '반품'을 남기고 싶습니까? –
나는 그것들이 함축되어 있다는 것을 읽었으며 그것들을 추가하는 것이 도움이되지 않는다. 이 경우 나는 그들이 반환과 함께 더 읽기 쉽다고 생각하지만, 그들은 합법적이지 않다. 결국,'cout << functionManip; '을 주석 처리하면 모든 것이 제대로 작동합니다. –
@EdKrohne :'return'은 ** 여기서는 선택 사항이 아닙니다 ** - 람다는 다른 함수와 마찬가지로 값을 반환하지 않고 'void'가 아닌 반환 유형을 사용하여 UB를 호출합니다. §6.6.3/2 : "* 함수의 끝에서 벗어나는 것은 값이없는'return'과 같습니다 : 이것은 값을 반환하는 함수에서 정의되지 않은 행동을합니다. *"잘 작동하는 것처럼 보이는 것은 단지 하나의 가능한 표현입니다 UB의 – ildjarn