Lambda函数,行为异常

费尼泽

假设我们在全局名称空间中声明了以下lambda:

auto Less = [](int a,int b) -> bool
{
    return a < b;
}

以及以下使用此lambda的代码:

template<typename T>
struct foo
{
    foo(int v){}
    bool operator<(const foo<T>&) const
    {
        return T(1,2);
    }
};

int main()
{
    typedef foo<decltype(Less)> be_less;
    priority_queue<be_less> data;
}

如您所见,我Less用作struct的模板参数foo对于g ++ 4.9.2,此代码无法编译:

test1.cpp:13:21: error: no matching function for call to '<lambda(int, int)>::__lambda0(int, int)'
     return T(1,2);
                 ^
test1.cpp:13:21: note: candidates are:
test1.cpp:17:14: note: constexpr<lambda(int, int)>::<lambda>(const<lambda(int, int)>&)
 auto Less = [](int a,int b) -> bool
          ^
test1.cpp:17:14: note:   candidate expects 1 argument, 2 provided
test1.cpp:17:14: note: constexpr<lambda(int, int)>::<lambda>(<lambda(int, int)>&&)
test1.cpp:17:14: note:   candidate expects 1 argument, 2 provided

我可能会添加两个小更改来解决此问题,首先,我需要将lambda更改为:

bool Less = [](int a,int b) -> bool
{
    return a < b;
}

如您所见,我只是被替换autobool,仅此修改仍然无效:

test1.cpp:13:21: error: expression list treated as compound expression in functional cast [-fpermiss
ive]
     return T(1,2);

除非我添加-fpermissive,否则我可以这样更改operator< bool

bool operator<(const foo<T>&) const
{
    return T((1,2));
}

注意双括号。现在,代码已编译,一切正常。

我的问题是,为什么auto Less不起作用但又bool Less起作用的技术原因是什么?

我相信我知道为什么第二个中需要双括号operator<,这是为了避免编译器将其解释T(1,2)为声明而不是调用。

谢谢你的时间

普雷托里亚人

在第一个示例中,您将构建foo<T>where [T = decltype(Less)]所以在这个表达

return T(1,2);

您正在尝试通过调用需要2 ints的构造函数来构造lambda的实例,这显然不存在。这正是错误消息告诉您的内容

error: no matching function for call to '<lambda(int, int)>::__lambda0(int, int)'

存在的唯一构造函数是lambda的复制和移动构造函数(从lambda表达式创建的闭包类型不是默认可构造的),编译器试图将其匹配参数,但失败

constexpr<lambda(int, int)>::<lambda>(const<lambda(int, int)>&)
constexpr<lambda(int, int)>::<lambda>(<lambda(int, int)>&&)
candidate expects 1 argument, 2 provided

在第二种情况下,通过进行此更改

bool Less = [](int a,int b) -> bool
{
    return a < b;
};

您要做的是声明一个名为的布尔变量Less,并将其初始化为true

这是因为您拥有的lambda表达式是无需捕获的,这意味着它可以隐式转换为指向函数的指针,该函数采用与lambda相同的参数,operator()并返回与原始lambda相同的类型。因此,您将lambda表达式转换为bool(*)(int,int)

接下来,函数指针可以隐式转换为bool并将始终求值true(假设它实际上指向函数的地址,在此执行)。因此Less被初始化为true

现在,decltype(Less)无非是bool所以在这里,您尝试将函数样式强制转换为bool,但传入2个参数

return T(1,2);

因此错误

error: expression list treated as compound expression in functional cast

通过添加额外的括号,您将得到一个由2个子表达式组成的表达式,该表达式由逗号分隔。这将评估并丢弃第一个子表达式(1),并返回第二个(2的值,然后将bool其转换为,因此将其转换为true


我不太确定您要尝试如何提出解决方案,但是如果您只想定义一些比较谓词foo,然后由调用priority_queue,那么以下工作可能呢?

struct foo
{
    foo(int v) {}
};

auto Less = [](foo const& a, foo const& b) -> bool
{
    return true; // do whatever comparison you need 
};

int main()
{
    using my_priority_queue = std::priority_queue<foo, std::vector<foo>, decltype(Less)>;

    my_priority_queue data(Less); // pass a copy of the comparator 
}

现场演示

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

getchar()函数的异常行为

来自分类Dev

fgets函数的行为异常

来自分类Dev

jQuery函数的异常行为

来自分类Dev

Python 函数的行为异常

来自分类Dev

Curry Lodash函数,行为异常

来自分类Dev

Python递归函数异常行为

来自分类Dev

函数中的 JavaScript 匿名函数行为异常

来自分类Dev

调用构造函数时异常的C ++行为

来自分类Dev

max_bucket_count函数的异常行为

来自分类Dev

类构造函数中异常处理的行为

来自分类Dev

python内置str函数的异常行为

来自分类Dev

R中setdiff()函数的异常行为

来自分类Dev

窗口函数first_value的异常行为

来自分类Dev

strncpy_s函数的异常行为

来自分类Dev

ArrayList到HashMap函数的行为异常

来自分类Dev

jQuery clone()函数插件内的行为异常

来自分类Dev

类构造函数中异常处理的行为

来自分类Dev

调用模板函数中的异常行为

来自分类Dev

Blender Game Engine中IF函数的异常行为

来自分类Dev

TypeScript String.split()函数的异常行为

来自分类Dev

Contiki中printf()函数中的异常行为

来自分类Dev

Tkinter after() 函数显示异常行为

来自分类Dev

了解python中的嵌套Lambda函数行为

来自分类Dev

Javascript函数(构造函数)返回类型中的异常行为

来自分类Dev

在AWS Lambda python函数中捕获异常

来自分类Dev

AWS Lambda函数中的异常为空

来自分类Dev

AWS cloudfront 无效的 Lambda 函数关联异常

来自分类Dev

使用for循环进行并发,匿名函数的行为异常

来自分类Dev

时间上的行为异常.Go中的解析函数