0

テンプレート特殊化クラスがあり、関数テンプレートをこのクラスのフレンドとして宣言する必要があります。MSVC コンパイラでコンパイルして正常に動作する次のコードを既に作成しましたが、code-warrior コンパイラでは動作しません。codewarrior コンパイラで機能させるには、テンプレート特殊化クラスの明示的な宣言のコメントを解除する必要があります。

これは codewarrior コンパイラの問題ですか、それともコードの問題ですか?

コンテキストを提供するためにコードサイズを縮小:

//template class
template<class R>
class Alice
{
    public:
            Alice() {}

    private:
        R review;

    template< class F>
    friend void Watch(F, Movie::Wonderland< Alice<R> >&, int);

};

//template specialization class
template<>
class Alice<void>
{
    public:
            Alice() {}

    private:
        int review;

    template<class F>
    friend void Watch(F, Movie::Wonderland< Alice< void > >&, int);

    /*
    //explicit declaration
    //need to uncomment this to compile on codewarrior 
    //as the function template above doesn't work.
    friend void Watch<void (*)()>(void (*)(), Movie::Wonderland<Alice<void> > &, int);
    */
};

完全なコード:

#define ONCE 1
#define NULL
namespace Movie{
template<class C>
class Wonderland
{
    public:
        Wonderland():who(NULL){}
        Wonderland(C* she):who(she){}
        void Attach(C *she)
        {who = she;}
        C* operator->()
        {return who;}
    private:
        C* who;
};
}
//fwd declarations
template<class R> class Alice;
void Watch(Movie::Wonderland< Alice<void> >& theatre, int price);
template<class F> void Watch(F func, Movie::Wonderland< Alice<void> >& theatre, int price);
template<class P, class F> void Watch(F func, P food, Movie::Wonderland< Alice<void> >& theatre, int price);
struct popcorn;

template<class R>
class Alice
{
    public:
            Alice() {}

    private:
        R review;

    friend void Watch(Movie::Wonderland< Alice<R> >&, int);

    template< class F>
    friend void Watch(F, Movie::Wonderland< Alice<R> >&, int);

    template<class P, class F>
    friend void Watch(F, P, Movie::Wonderland< Alice<R> >&, int);
};

template<>
class Alice<void>
{
    public:
            Alice() {}

    private:
        int review;

    friend void Watch(Movie::Wonderland< Alice< void > >&, int);

    template<class F>
    friend void Watch(F, Movie::Wonderland< Alice< void > >&, int);

    template<class P, class F>
    friend void Watch(F, P, Movie::Wonderland< Alice< void > >&, int);

    /*
    //explicit declarations
    friend void Watch(Movie::Wonderland<Alice<void> > &, int);
    friend void Watch<void (*)()>(void (*)(), Movie::Wonderland<Alice<void> > &, int);
    friend void Watch<void (*)(), void (*)()>(void (*)(), void (*)(), Movie::Wonderland<Alice<void> > &, int);
    friend void Watch<popcorn, void (*)()>(void (*)(), popcorn, Movie::Wonderland<Alice<void> > &, int);
    */
};

//template<class R>
void Watch(Movie::Wonderland< Alice<void> >& theatre, int price) 
{
    theatre.Attach(new Alice<void>);
    int review = theatre->review;
    return;
}

template<class F>
void Watch(F func, Movie::Wonderland< Alice<void> >& theatre, int price) 
{
    theatre.Attach(new Alice<void>);
    int review = theatre->review;
    return;
}

template<class P, class F>
void Watch(F func, P food, Movie::Wonderland< Alice< void > >& theatre, int price)
{
    theatre.Attach(new Alice<void>);
    int review = theatre->review;
    return;
}

void goWatch(void)
{
    return;
}

void eatPopcorn(void)
{
    return;
}

struct popcorn
{

};

int main()
{
    struct popcorn sweetPopcorn;
    Movie::Wonderland< Alice<void> > theatre;
    Watch(goWatch, theatre, ONCE);
    Watch(goWatch, eatPopcorn, theatre, ONCE);
    Watch(theatre, ONCE);
    Watch(goWatch, sweetPopcorn, theatre, ONCE);
}
4

1 に答える 1

1

私はあなたのコードをレビューし、g++-4.2とclang++の2つのコンパイラに対してテストしました。友達の宣言に関しては何の問題もありません。

于 2011-03-13T19:58:49.373 に答える