【问题标题】:Class with non-static lambda member can't use default template paramers?具有非静态 lambda 成员的类不能使用默认模板参数?
【发布时间】:2012-09-21 23:47:03
【问题描述】:

这个小测试程序:

#include <functional>

//template<class T>            // <-- with this, gcc compiles  ok
template<class T=void>
struct  c{
        std::function<int(int)> f = [](int i){return i+i;};
};

int main() {};

Clang-3.2 可以编译,但是从 GCC 4.7.1 和 4.8 开始出现奇怪的错误:

t.cc:6:31: error: default argument for template parameter for class enclosing ‘struct __lambda0’
  function<int(int)> f = [](int i){return i+i;};
                               ^

这是没有人知道的那些晦涩难懂的 C++ 规则例外之一,还是 GCC 错误?

编辑 看起来像一个错误。我已经提交了bug report

【问题讨论】:

  • 默认类怎么可能是void
  • 在此上下文中,classtypename 相同 - 一种类型。您可以将void 替换为任何其他类型。
  • 即使实际实例化模板,clang 也可以吗?
  • @6502 - 是的,如果我在main 中添加c&lt;int&gt; t;,则可以使用clang
  • 只是因为你语法错误!如果您尝试创建结构的实例,您将收到错误。

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


【解决方案1】:

我认为这是一个带有默认成员初始化的 g++ 错误。我对此并不肯定,因此有以下支持证据:

template<class T=void>
struct  c {
   std::function<int(int)> f;
   c() : f([](int i){return i+i;}) {
   }
};

int main() {}

如果这有效,那么您所做的也应该有效。它确实如此,即使你构造了一个c

就个人而言,我认为应该谨慎使用默认成员初始化。我认为它很容易造成很多混乱,因为大多数人希望所有初始化都在构造函数中完成,并且成员初始化器不一定靠近任何构造函数。所以他们可能会让一些人摸不着头脑,想知道某个成员是如何获得特定价值的。

我可以看到一些案例,尤其是对于简单的、主要是数据的类,它可以很好地工作。但大多数情况下,我认为如果您有任何类型的构造函数主体,您可能不应该使用默认成员初始化。

【讨论】:

    【解决方案2】:

    此代码在gcc 上无论如何都会出错。是的,没有默认参数它可以被编译。它可以被编译,因为struct c 没有在任何地方使用。但是如果你尝试创建这个结构的实例,你会得到错误。

    #include <functional>
    
    template<class T>
    struct c {
        std::function<int(int)> f = [](int i){return i+i;};
    };
    
    int main() {
        c<int> _c; // error
    }
    

    它看起来像gcc 的错误。这种方式可以帮助避免问题。

    #include <functional>
    #include <iostream>
    
    template<class T=void>
    struct c {
       c() : f([](int i){return i+i;}) {
       }
    
       std::function<int(int)> f;
    };
    
    int main() {
       c<> _c; 
       std::cout << _c.f(10) << std::endl;
    }
    

    【讨论】:

    • 我不太清楚你所说的类和结构不能保持默认值是什么意思。你是说this 不起作用吗?
    • 这不是真的。您可以在 C++11 中的构造函数之外进行默认成员初始化。请参阅此 Wikipedia 部分中的最终示例:en.wikipedia.org/wiki/C%2B%2B11#Object_construction_improvement
    • @Omnifarious 这是我的错。当然可以。真的看起来像一个错误。
    猜你喜欢
    • 2011-05-31
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 2013-05-11
    • 1970-01-01
    • 2017-10-16
    • 2021-12-07
    相关资源
    最近更新 更多