【问题标题】:Should lambda decay to function pointer in templated code?lambda 是否应该衰减为模板代码中的函数指针?
【发布时间】:2011-03-10 12:15:40
【问题描述】:

我在某处读到,如果捕获列表为空,则 lambda 函数应衰减为函数指针。我现在能找到的唯一参考是n3052。使用 g++(4.5 和 4.6)它可以按预期工作,除非在模板代码中声明了 lambda。

例如下面的代码编译:

void foo() {
    void (*f)(void) = []{};
}

但是当模板化时它不再编译(如果foo实际上在其他地方被调用):

template<class T>
void foo() {
    void (*f)(void) = []{};
}

在上面的参考资料中,我没有看到对这种行为的解释。这是 g++ 的临时限制吗?如果不是,是否有(技术)理由不允许这样做?

【问题讨论】:

  • 请注意,您引用的 N3052 确实已合并到 C++0x FCD (N3092 5.1.2/6) 中。 Visual C++ 2010 根本没有实现转换(不足为奇,因为允许它的语言在 VC++ 发布之前很快就被纳入标准)。我已经提交了一份关于 Microsoft Connect 的错误报告(尽管我预计在下一个 Visual C++ 版本之前它不会被修复):connect.microsoft.com/VisualStudio/feedback/details/572138/…
  • 仅供参考:英特尔 C++ 11.1 不支持上述代码
  • 它已经在 GCC 的 bugtracker 中,但目前尚未确认:gcc.gnu.org/bugzilla/show_bug.cgi?id=45080
  • @James Noob 问题(也对提问者)。鉴于函数指针捕获列表对于 lambda 集合是空的,我们可以在不使用 std::function 的情况下将它们存储在容器中(对于我遇到的情况来说很昂贵......)?对此已经两年抱歉了,只是偶然发现了这个页面并且很好奇......

标签: c++ templates lambda c++11 function-pointers


【解决方案1】:

我想不出任何理由会明确禁止它。我猜这只是g++的暂时限制。

我还尝试了其他一些方法:

template <class T>
void foo(void (*f)(void)) {}

foo<int>([]{});

这行得通。

typedef void (*fun)(void);

template <class T>
fun foo() { return []{}; } // error: Cannot convert.

foo<int>()();

不会(但如果 foo 未参数化,则会这样做)。

注意:我只在 g++ 4.5 中测试过。

【讨论】:

  • 是的,在第一种情况下,lambda 是在代码的非模板部分声明的(尽管它被模板函数使用)。在模板类中声明 lambda 时也会出现同样的问题。
猜你喜欢
  • 2017-05-10
  • 2014-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 2011-11-14
  • 2016-10-25
  • 2015-03-30
相关资源
最近更新 更多