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は問題なくコンパイルしますが、GCC4.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 ++ルールの例外の1つですか、それとも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 に答える