Можно ли сделать функцию шаблона дружественной для класса специализации шаблона? - PullRequest
0 голосов
/ 16 декабря 2010

У меня есть класс специализации шаблонов, и мне нужно объявить шаблон функции в качестве друга этого класса.Я уже создал следующий код, который компилируется и хорошо работает на компиляторе MSVC, но он не работает на компиляторе кода-воина.Чтобы заставить его работать на компиляторе 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);
}

1 Ответ

1 голос
/ 13 марта 2011

Я рассмотрел ваш код и проверил его на двух компиляторах: g ++ - 4.2 и clang ++. Я не вижу никаких проблем с заявлениями ваших друзей.

...