【问题标题】:Lambda Syntax Incompatibility between MSVC and GCCMSVC和GCC之间的Lambda语法不相容
【发布时间】:2016-08-18 22:10:20
【问题描述】:

我在 C++ 标头中创建了一个具有以下签名的方法:

template<class _Ty>
class x {
public:

    // ...

    template<class func_Ty>
    x *where(func_Ty &);
}

我的代码期望func_Ty 是可调用的(即函数指针、lambda 或重载operator() 的类),采用_Ty_Ty &amp; 类型的单个参数,并返回bool 或@ 987654328@。我用这段代码调用函数(sx&lt;int&gt; *):

s->where([](int i){ return i % 2 == 0;});

这在 MSVC 上编译得很好,但 GCC 给了我一个错误:

no matching function for call to ‘x<int>::where(main()::__lambda0)’

如果我在 lambda 前面添加 *,GCC 编译正常,但 MSVC 给我一个错误:

error C2100: illegal indirection

这是其中一个编译器的错误吗?或者这两种解决方案都不是标准的?无论哪种方式,有没有办法让相同的代码在两个编译器上工作?

【问题讨论】:

  • 为什么不使用std::remove_if
  • 与您的问题完全无关,但您不应使用前导下划线后跟大写字母来命名任何符号,例如 are reserved for the "implementation" (编译器和标准库)。
  • 以下划线开头后跟大写字母 (_Ty) 和包含两个连续下划线的名称保留给实现。不要使用它们。
  • @erip 我现在看到它可以代替我的 where 函数工作,但是这并不能解决 lambda 语法问题,它可以转移到其他场景。
  • @JoachimPileborg 谢谢,我不知道

标签: c++ c++11 gcc visual-c++ lambda


【解决方案1】:

据我所知,它是一个允许非常量引用绑定到临时对象的 VS 扩展。标准不允许这样做。

lambda 是临时的,where 的参数是非常量引用。

所以改变:

x *where(func_Ty &);

x *where(const func_Ty &);

x *where(func_Ty);

这个

template<class func_Ty>
x *where(func_Ty&&);

也可以,因为在这种情况下它是一个转发参考。

【讨论】:

  • 您可能还想回答问题的第二部分
  • 谢谢您,这非常有效。我不敢相信我错过了那个细节。我会尽快接受
  • @MagikM18 或func_Ty&amp;&amp;,在此上下文中是一个转发引用,将绑定到左值和右值(临时或非临时)。
  • @bolov 用于非捕获 lambda,也许这首先会触发到函数指针的转换,然后将其取消引用,但不确定
  • @bolov:如果 lambda 具有“指向函数的指针...”类型,那么取消引用会将其转换为“函数...”,这将衰减为“指向函数的指针... “ 立即地。除非在这种情况下 C++ 与 C 有一些不同之处。有趣的效果是,您可以通过函数指针以多种方式调用函数,例如(*fptr)(1)fptr(1)(********fptr)(1)
猜你喜欢
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
  • 2019-06-24
相关资源
最近更新 更多