为什么这个c ++ lamba函数不会编译? [英] Why won't this c++ lamba function compile?

查看:149
本文介绍了为什么这个c ++ lamba函数不会编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么无法编译:

int myVar = 0;
myVar ? []()->void{} : []()->void{};

出现以下错误msg:


错误2错误C2446:':':没有从'red_black_core ::`anonymous-namespace':: < lambda1>'to red_black_core :: anonymous-namespace ::< lambda0>

Error 2 error C2446: ':' : no conversion from 'red_black_core::`anonymous-namespace'::< lambda1>' to red_black_core::anonymous-namespace::< lambda0>

这符合以下条件:

void left()
{}
void right()
{}

int myVar = 0;
myVar ? left() : right();


推荐答案

草案n3225中的条件运算符规则说

Rules for conditional operator in the draft n3225 says at one point


否则,结果是prvalue。如果第二和第三操作数不具有相同的类型,并且
具有(可能是cv-qualal)类类型,则重载分辨率被用于确定转换(如果有)为
应用于操作数(13.3.1.2,13.6)。如果过载分辨率失败,程序不成形。否则,应用
这样确定的转换,并且使用转换的操作数代替本节其余部分的原始
操作数。

Otherwise, the result is a prvalue. If the second and third operands do not have the same type, and either has (possibly cv-qualified) class type, overload resolution is used to determine the conversions (if any) to be applied to the operands (13.3.1.2, 13.6). If the overload resolution fails, the program is ill-formed. Otherwise, the conversions thus determined are applied, and the converted operands are used in place of the original operands for the remainder of this section.

到那时,所有其他替代方法(例如,将一个转换为另一个操作数)失败,因此我们现在将执行该段所述。我们将应用的转换是通过重载分辨率转换 a来确定的? b:c 到运算符?(a,b,c)(对所谓函数的虚函数调用)。如果你看看虚拟运算符的候选者是什么,你会发现

Up to that point, every other alternative (like, convert one to the other operand) failed, so we will now do what that paragraph says. The conversions we will apply are determined by overload resolution by transforming a ? b : c into operator?(a, b, c) (an imaginary function call to a so-named function). If you look what the candidates for the imaginary operator? are, you find (among others)


对于每个类型T,其中T是指针,指向成员的指针或范围枚举类型,存在以下形式的候选运算符函数:

For every type T , where T is a pointer, pointer-to-member, or scoped enumeration type, there exist candidate operator functions of the form

T operator?(bool, T , T );


这包括 T 是类型 void(*)()。这很重要,因为lambda表达式产生一个可以转换为这种类型的类的对象。规范说

And this includes a candidate for which T is the type void(*)(). This is important, because lambda expressions yield an object of a class that can be converted to such a type. The spec says


没有lambda捕获的lambda表达式的闭包类型具有公共非虚拟非显式const转换函数指向具有与闭包类型的函数调用操作符相同的参数和返回类型的函数的指针。这个转换函数返回的值应该是一个函数的地址,当被调用时,函数调用闭包类型的函数调用操作符的效果相同。

The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.

lambda表达式不能转换为列出的任何其他参数类型,这意味着重载解析成功,找到一个运算符? lambda表达式到函数指针。然后,条件运算器部分的其余部分照常进行,现在具有用于具有相同类型的条件运算符的两个分支。

The lambda expressions can't be convert to any other of the parameter types listed, which means overload resolution succeeds, finds a single operator? and will convert both lambda expressions to function pointers. The remainder of the conditional opreator section will then proceed as usual, now having two branches for the conditional operator having the same type.

这就是为什么你的第一个版本是OK,为什么GCC正确接受它。但是我真的不明白为什么你显示第二个版本 - 正如其他人解释,它做一些不同的事情,这并不奇怪,它的工作原理而另一个没有(在你的编译器)。下次,最好尽量不要将无用的代码包含在问题中。

That's why also your first version is OK, and why GCC is right accepting it. However I don't really understand why you show the second version at all - as others explained, it's doing something different and it's not surprising that it works while the other doesn't (on your compiler). Next time, best try not to include useless code into the question.

这篇关于为什么这个c ++ lamba函数不会编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆