Tôi đang cố gắng sử dụng các tính năng C++ 11 để tạo các trình xử lý luồng tùy chỉnh dễ dàng hơn để tạo. Tôi có thể sử dụng hàm lambda làm thao tác, nhưng không sử dụng std::function<ostream&(ostream&)>
.std :: chức năng như một trình xử lý dòng tùy chỉnh
Dưới đây là đoạn code, luộc xuống:
#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
}
Thứ hai cout
tuyên bố không thành công với những điều sau đây:
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>&)>]'
Tại sao điều này không? Tôi đang sử dụng Cygwin gcc 4.5.3.
Trong khi tôi hỏi, tôi không phải lo về việc sử dụng std::function
ở mọi nơi, do các vấn đề về hiệu quả. Nhưng tôi muốn viết các hàm trả về các hàm lambda, và không biết làm thế nào để làm như vậy mà không có std::function
. Ví dụ: một số nội dung như sau sẽ tuyệt vời
auto getAdditionFunctor();
auto getAdditionFunctor() {
return [] (int x, int y) { return x + y };
};
... nhưng rõ ràng là không hoạt động. Có cú pháp thay thế nào hoạt động không? Tôi không thể tưởng tượng nó có thể là gì, vì vậy tôi có thể bị mắc kẹt với std::function
.
Nếu tôi có giải pháp cho câu hỏi thứ hai, thì câu hỏi đầu tiên sẽ là tranh luận.
Cảm ơn bạn.
Xác định operator<<(ostream&, std::function<ostream&(ostream&)>
đã giúp. Tôi đã đọc sai một trang web và theo ấn tượng rằng ostream
đủ thông minh để xử lý một đối tượng tùy ý có số operator()
làm người thao túng. Tôi đã sai về điều này. Hơn nữa, đơn giản lambda
Tôi xây dựng có lẽ chỉ được biên dịch thành một chức năng cũ đơn giản, giống như tôi đã nói. Thật vậy, nếu tôi sử dụng chụp biến để đảm bảo rằng lambda
không phải là một chức năng đơn giản, thì trình biên dịch không thành công. Ngoài ra, các đối tượng với operator()
định nghĩa là không (theo mặc định) được coi là thao tác:
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
}
cập nhật thêm: hóa ra một giải pháp nhẹ mạnh mẽ hơn những người dưới đây có thể được thực hiện với:
// 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);
}
Mã này có thêm const
. Tôi phát hiện ra điều này đang cố gắng thực sự triển khai giải pháp trong dự án của tôi.
Bạn có ý định bỏ qua 'trở lại' trong các thao tác đó không? –
Tôi đã đọc rằng những điều đó được ngụ ý và việc thêm chúng không giúp ích gì. Trong trường hợp này, tôi nghĩ rằng chúng dễ đọc hơn với lợi nhuận, nhưng chúng không hợp pháp. Sau khi tất cả, tất cả mọi thứ hoạt động tốt nếu tôi nhận xét 'cout << functionManip;'. –
@EdKrohne: 'return' là ** không ** tùy chọn ở đây - lambdas của bạn gọi UB bằng cách không có kiểu trả về' không 'và không trả về một giá trị, giống như với bất kỳ hàm nào khác. §6.6.3/2: "* Chảy ra khỏi đầu của một hàm tương đương với' return' không có giá trị; kết quả là hành vi không xác định trong hàm trả về. * "Xuất hiện để làm việc tốt chỉ là một biểu hiện có thể của UB. – ildjarn