c++ 为什么在VisualStudio 2013中,lambda的operator+是不明确的?

6yt4nkrj  于 9个月前  发布在  其他
关注(0)|答案(2)|浏览(106)

有人能帮我指出为什么这在VS 2013中不起作用吗?

auto p = +[]() -> void { std::cout << "Hello, world!\n"; };
p();

source_file.cpp(7) : error C2593: 'operator +' is ambiguous
    could be 'built-in C++ operator+(void (__cdecl *)(void))'
    or       'built-in C++ operator+(void (__stdcall *)(void))'
    or       'built-in C++ operator+(void (__fastcall *)(void))'
    or       'built-in C++ operator+(void (__vectorcall *)(void))'

字符串
这是强制转换lambda的法律的运算符

5.1.2 Lambda表达式[expr. lambda.lambda]

6不带 * resida-capture * 的 * resida-expression * 的闭包类型有一个公共的非虚的非显式的const转换函数,该转换函数指向具有与闭包类型的函数调用操作符相同的参数和返回类型的函数。这个转换函数返回的值应该是一个函数的地址,当调用这个函数时,它的效果与调用闭包类型的函数调用操作符相同。
我如何告诉编译器他应该使用什么转换?

dzjeubhm

dzjeubhm1#

显然这是一个VC++ bug。除了显式强制转换之外,似乎没有其他方法:

+ static_cast< void(*)() >( []{} ); // Empty lamba without loss of generality

字符串
不幸的是,魔法就这样消失了。

xxls0lw8

xxls0lw82#

我找到了一个解决问题的方法。我第一篇文章中的第一个问题可以通过使用C-Cast来解决,给予编译器一个提示,告诉编译器 * p * 应该是什么类型,而不使用一元+运算符。

using ExplicitCast = void();
// valid but does not work in MSVC
auto fn = +[]() {};
// fix for MSVC
auto fn = (ExplicitCast*)[]() {};

字符串
不幸的是,当参数列表中的类型不匹配时,这并不能解决问题(如果类型是继承的,这是法律的)。我有一个函数,其中第一个参数与lambda中的第一个参数不同。例如:

class Foo {};
class Bar : public Foo {};

using ExplicitCast = void(Bar*);
using Function = void(Foo*);
static Function* func = nullptr;

int main()
{
    // does not work because the parameter list does not match
    // func = [](Bar*) -> void { };
    // func = +[](Bar*) -> void { };

    // does work because we first explicit cast to a function and then to the needed function.
    func = (Function*)(ExplicitCast*)[](Bar*) -> void { };

    Bar o;
    func(&o);

    return 0;
}

相关问题