4

这个小测试程序:

#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 错误?

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

4

2 回答 2

4

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

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

int main() {}

如果这行得通,那么您正在做的事情也应该行得通。它确实如此,即使你构造了一个c.

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

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

于 2012-10-01T06:31:26.503 回答
0

这段代码无论如何都会出错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;
}
于 2012-10-01T06:31:59.920 回答