具有可选返回值的 lambda 参数
lambda parameter with optional return value
我正在尝试编写一个像std::for_each
这样的函数,除了正常用法外,还可以std::function<bool (param)>
。错误的返回值意味着我想脱离循环。下面的代码是我到目前为止得到的。
对 a.visit([&](int) -> void)
的第二次调用在评估 !visitor(i) 时不编译。是否有可能完成这项工作,还是我吠错了树?
我使用的是 MSVC 2010,但希望代码通常与 C++11 兼容。
#include <list>
#include <string>
#include <iostream>
struct A
{
std::list<int> _lst;
template<typename _F>
void visit(_F visitor)
{
for(std::list<int>::const_iterator it = _lst.begin(), end = _lst.end() ; it != end ; it++) {
int i = *it;
if (std::is_void<decltype(visitor(i))>::value) {
visitor(i);
} else {
if (!visitor(i)) { // <----- error C2171: '!' : illegal on operands of type 'void'
break;
}
}
}
}
};
int main(int argc, char* argv[])
{
A a;
// populate a
for (int i = 0 ; i < 10 ; i++) {
a._lst.push_back(i);
}
a.visit([](int i) -> bool {
std::cout << i << std::endl;
return i < 5;
});
a.visit([](int i) {
std::cout << i << std::endl;
});
}
这是我实现for_almost_each
的方式;出于可读性的目的,我using namespace std
加上类型别名。
#include <algorithm>
#include <iterator>
#include <functional>
using namespace std;
template<class Iter, class Func>
Iter
for_almost_each_impl(Iter begin, Iter end, Func func, std::true_type)
{
for (auto i = begin; i!=end; ++i)
if (!func(*i))
return i;
return end;
}
template<class Iter, class Func>
Iter
for_almost_each_impl(Iter begin, Iter end, Func func, std::false_type)
{
for_each(begin, end, func);
return end;
}
template<class Iter, class Func>
Iter for_almost_each(Iter begin, Iter end, Func func)
{
using Val = typename iterator_traits<Iter>::value_type;
using Res = typename result_of<Func(Val)>::type;
return for_almost_each_impl(begin, end,
func,
is_convertible<Res, bool>{} );
}
我用了is_convertible
,因为它似乎比is_same
更有意义。
你的 std::is_void 需要在编译时完成,不能在函数体内完成。这种函数重载的使用将起作用:
#include <list>
#include <string>
#include <iostream>
#include <type_traits> // missing header
struct A
{
std::list<int> _lst;
// wrapper for bool returning visitor
template<typename _F, typename Iter>
bool do_visit(_F visitor, Iter it, std::true_type)
{
return visitor(*it);
}
// wrapper for non-bool returning visitor
template<typename _F, typename Iter>
bool do_visit(_F visitor, Iter it, std::false_type)
{
visitor(*it);
return true;
}
template<typename _F>
void visit(_F visitor)
{
for (auto it = _lst.begin(), end = _lst.end() ; it != end ; it++) {
// select correct visitor wrapper function using overloading
if (!do_visit(visitor, it, std::is_same<bool, decltype(visitor(0))>())) {
break;
}
}
}
};
int main(int argc, char* argv[])
{
A a;
// populate a
for (int i = 0 ; i < 10 ; i++) {
a._lst.push_back(i);
}
a.visit([](int i) -> bool {
std::cout << i << std::endl;
return i < 5;
});
a.visit([](int i) {
std::cout << i << std::endl;
});
}
此 lambda 不返回值,这就是为什么您收到"visitor"返回 void 的错误:
a.visit([](int i) {
std::cout << i << std::endl;
});
您可以通过重写为:
a.visit([](int i) -> bool {
std::cout << i << std::endl;
return true;
});
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 使用自动推导的 lambda 参数作为常量表达式
- 如何参数化用作另一个 lambda 参数的 lambda
- 有没有办法根据 lambda 参数返回类型部分专用化我的模板化函数?
- 从成员函数签名中自动推导lambda参数
- Clang声称通用lambda参数的constexpr成员不是constexpr
- 如果我的模板类型首先以lambda参数而发生,则MSVC会引起一个奇怪的错误
- 继承类中没有匹配的泛型委托作为 lambda 参数
- 为什么在lambda参数中不允许自动
- 如何定义通用 lambda 参数的模板参数?
- 在 QGraphicsScene 中拖动 QPixmap:如何避免 lambda 参数中不允许'auto'
- variadic模板函数会以相反的顺序调用lambda参数
- 可变模板lambda参数的模板推导
- 嵌套模板功能中的C 0x lambda参数
- 带有 std::函数和 lambda 参数的分段错误
- 从值捕获的变量分配到lambda参数时,GCC编译器分割故障
- 标准::p空气的通用 lambda 参数
- C++ lambda 参数列表
- 我的 lambda 参数真的在阴影我的当地人吗?
- 从常量和引用的角度来看,函数应该如何接受*lambda*参数