Tôi đang cố gắng cung cấp một hàm gọi là lambda được cung cấp và tôi tự hỏi liệu có thể trả về giá trị mặc định nếu hàm trả về loại void
hay không.Bất kỳ cách nào để khớp với giá trị trả về trong C++ 11?
Dưới đây là những gì tôi có cho đến nay, một hàm trả về giá trị trả về của lambda, nhưng nếu lambda là void
, sau đó nó sẽ trả về 20.
#include <functional>
#include <iostream>
template <typename H>
auto f(H&& h) -> decltype(h(), void())
{
return h();
}
template <typename H>
auto f(H&& h) -> decltype(h(), int())
{
h();
return 20;
}
int main()
{
int r = f([](){ std::cout << "test1" << std::endl; return 10; }); // error here
std::cout << "r: " << r << std::endl;
r = f([](){ std::cout << "test2" << std::endl; });
std::cout << "r: " << r << std::endl;
return 0;
}
này tạo ra các lỗi,
test.cpp:20:68: error: call of overloaded ‘f(main()::<lambda()>)’ is ambiguous
Vì vậy, rõ ràng đây chỉ là do C++ không thể sử dụng đa hình dựa trên kiểu trả về. Tuy nhiên, tôi tự hỏi nếu có bất kỳ thủ thuật C++ 11 tốt, chẳng hạn như sử dụng tốt hơn của decltype
hoặc một số ma thuật mẫu, có thể làm cho điều này có thể? Tôi yêu cầu bởi vì theo như tôi có thể thấy không có sự mơ hồ thực sự ở đây .. trình biên dịch suy ra loại trả về void
và sau đó nói rằng nó không rõ ràng có khớp với phiên bản int
hoặc void
của f
, một chút ngớ ngẩn.
Lý do để làm điều này là nếu hàm f
mong đợi giá trị trả lại nhưng người dùng cung cấp lambda không bao gồm câu lệnh return
, trình biên dịch sẽ nhập loại void
và lỗi. Vì trong kịch bản thực, tôi có ý tưởng tốt về giá trị trả về mặc định hợp lý nên khi người dùng không quan tâm đến việc cung cấp giá trị, tôi tự hỏi liệu có thể có trình biên dịch cho phép người dùng bỏ qua câu lệnh thường gặp không cần thiết return
cho thuận tiện.
Cảm ơn. Tôi nên đề cập rằng tôi đang sử dụng GCC 4.6.3.
trả lời: dựa trên gợi ý của việc sử dụng enable_if
Xéo, tôi đã đưa ra những điều sau đây, mà dường như làm việc:
template <typename H>
auto f(H&& h) -> typename std::enable_if<std::is_same<decltype(h()), void>::value, int>::type
{
h();
return 20;
}
template <typename H>
auto f(H&& h) -> typename std::enable_if<std::is_same<decltype(h()), int>::value, int>::type
{
return h();
}
Cảm ơn!
bạn đã thử nghiệm f trên các chức năng bình thường không? – CharlesB
Có, trên các chức năng bình thường, nó cũng không rõ ràng. – Steve
Tham số thứ hai của 'decltype': Tôi có thể hỏi nó là gì? (Thực sự, bởi vì tôi không biết!). – 0x499602D2