1

このようなクラスを作成しました。重要なのは、メインのテンプレート引数と、デフォルトのテンプレート基本クラスがあることです。テンプレート化されたコピーコンストラクターもあります...

struct default_base{};

template <typename T, typename TBase=default_base>
class some_class : public TBase{
public:
    some_class(){}
    template <typename U, typename UBase>
    some_class(const some_class<U,UBase>& u){
        T t(U());
    }
};


int main(){
    some_class<int> a;
    return 0;
}

このうっとうしい漠然としたコンパイラ エラーが発生し、エラーを見つけることができませんでした。gcc 4.8.1 を使用しています。

g++ -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\stuff.o" "..\\src\\stuff.cpp" 
..\src\stuff.cpp: In constructor 'some_class<T, TBase>::some_class(const some_class<U,     UBase>&)':
..\src\stuff.cpp:87:10: error: default argument for template parameter for class     enclosing 'T t(U (*)())'
   T t(U());
      ^
..\src\stuff.cpp: In function 'int main()':
..\src\stuff.cpp:104:16: error: wrong number of template arguments (1, should be 2)
  some_class<int> a;
            ^
..\src\stuff.cpp:82:7: error: provided for 'template<class T, class TBase> class   some_class'
 class some_class : public TBase{
   ^
..\src\stuff.cpp:104:19: error: invalid type in declaration before ';' token
  some_class<int> a;

編集:答えを見つけてください、乾杯:-)それでもコンパイルする必要があると思っていても...これはコンパイルされます...

template <typename T>
struct some_other_class{
some_other_class(){}
    template <typename U>
    some_other_class(){
        T t(U());
    }
};
4

2 に答える 2

7
T t(U());

いわゆる「一番厄介なパース」です。Tを返し、Uを返す空関数をパラメータとする関数宣言です。想像:

typedef U nullary_function_return_U();
T t(nullary_function_return_U /*param_name*/)
{
    return T;
}

括弧を追加することで回避できます。

T t( (U()) );

または C++11 では、統一された初期化構文を使用できます。

T t{U{}};

エラーメッセージは本当にひどいもので、最も厄介な解析に関係なく、実際にコンパイルする必要がありますね。

GCC 4.8.1 - エラー、Clang 3.4 - OK、MSVC2010 - OK でテストしました。GCCでエラーを引き起こす最小のケースに切り詰めました:

template <typename = int>
struct Foo
{
    Foo()
    {
        int t(int()); // Error
    }
};

int main()
{
    int t(int()); // OK
    Foo<> a; // Error
}

これは GCC のバグのようです。GCC Bugzillaに報告しました。


編集

Paolo Carlini 2014-07-07 14:11:14 UTC これはすでにメインラインと 4.9.1 で修正されています。テストケースを追加し、バグを閉じています。

于 2013-10-28T00:18:35.010 に答える
1

引数としてt返される関数を取り、 を返すという名前の関数を本当に宣言しますか? たとえば、次を使用して変数を宣言する宣言のあいまいさを解消する場合UTt

T t{U()};

gcc は宣言に満足しているようです。

于 2013-10-28T00:27:32.727 に答える