0

これはコンパイルされます:

template <class T>
class Bar {};

template<class T, class Dummy=void>
class Foo;

template<class T>
class Foo <T, typename std::enable_if<
    std::is_base_of<Bar<T>, T>::value
>::type> {
    public:
        //THIS CHANGES IN THE 2ND SNIPPET
        void test () const {
            std::cout << "test";
        }
};

class Cat : Bar<Cat> {};

int main () {
    Foo<Cat> foo;
    foo.test();
    return 0;
}

このエラー:

template <class T>
class Bar {};

template<class T, class Dummy=void>
class Foo;

template<class T>
class Foo <T, typename std::enable_if<
    std::is_base_of<Bar<T>, T>::value
>::type> {
    public:
        //THIS CHANGED!
        void test () const;
};

//THIS WAS ADDED SINCE THE 1ST SNIPPET!
template<class T>
void Foo<T>::test () const {
    std::cout << "test";
} //error C2039: 'test' : is not a member of 'Foo<T>'

class Cat : Bar<Cat> {};

int main () {
    Foo<Cat> foo;
    foo.test();
    return 0;
}

違いをマークしました。2 番目のコード スニペットでエラーが発生するのはなぜですか? エラーを回避しながら、宣言と定義を別々に保つにはどうすればよいですか?

私はこれと関係があると推測しています: "template void Foo::test () const"

同様に、これはメソッドtest() constテンプレート クラス template class Fooのメソッドであることをコンパイラに伝える間違った方法です。 T>::value >::type>

もちろん、Google と StackOverflow で調べましたが、テンプレートでこのエラーが表示されるたびに、毎回異なる理由があるようです。(おそらく、多くのことが原因で C2039 エラーが発生する可能性があります。)

また、mod. または誰かがこの投稿にC2039タグを追加するのを手伝ってくれますか? 分が必要だと言っています。1500レップの そのタグを追加します。

-- とりとめのない -- 私が C++ を使用してからしばらく経っていることにも注意してください。テンプレートを使用してからさらに長くなります。これがテンプレートの使用方法としては奇妙かもしれないことは承知していますが、正当な理由があることは保証できます。

4

1 に答える 1

1

部分的に特殊化されたクラス テンプレートのクラス外メンバー宣言の例は、14.5.4.3/1 (C++03) に示されています。そして、これはそれがどのように見えるかです

// primary template
template<class T, int I> struct A {
  void f();
};

// class template partial specialization
template<class T> struct A<T,2> {
  void g();
};

// member of class template partial specialization
template<class T> void A<T,2>::g() { }

ご覧のとおり、クラス外のメンバー定義で特殊な引数を指定する必要があります。

あなたの場合、それはあるべきです

template<class T>
void Foo<T, typename std::enable_if<
  std::is_base_of<Bar<T>, T>::value>::type>::test () const {
    std::cout << "test";
}
于 2013-07-07T04:36:08.640 に答える