2012-10-01 40 views
4

这个小测试程序:带有非静态lambda成员的类不能使用默认模板参数?

#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() {}; 

锵-3.2编译就OK了,但是从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

+0

默认类怎么能'void'? –

+0

在这种情况下'class'的意思与'typename'相同 - 一种类型。你可以用任何其他类型来替换'void'。 –

+0

即使你真的实例化模板,它在叮当中是否可以? – 6502

回答

4

我认为这是一个g ++的bug,默认成员初始化。我对此并不积极,因此有以下证据支持:

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

int main() {} 

如果这样的话,那么你在做什么也应该起作用。即使你构建了一个c也是如此。

就我个人而言,我认为应谨慎使用默认成员初始化。我认为很容易让它产生混淆,因为大多数人都期望所有的初始化都在构造函数中完成,并且成员初始化符不一定在任何构造函数附近。所以他们可以让某人挠头,想知道某个成员如何获得特定价值。

我可以看到案例,特别是对于简单的,主要是数据类,它会工作得很好。但大多数情况下,我认为如果你有任何形式的构造函数体,你可能不应该使用默认的成员初始化。

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; 
} 
+0

我不太清楚你的意思*类和结构不能保持默认值。*你是说[this](http://liveworkspace.org/code/ac2651b89f63d02378c5e45e66a14fb4)不起作用吗? – chris

+0

这是不正确的。您可以在C++ 11的构造函数之外进行默认成员初始化。请参阅本维基百科章节的最后一个示例:http://en.wikipedia.org/wiki/C%2B%2B11#Object_construction_improvement – Omnifarious

+0

@Omnifarious这是我的错。当然可以。真的看起来像一个错误。 – fasked

相关问题