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