我有一个模板专业化类,我需要将一个函数模板声明为这个类的朋友。我已经创建了以下代码,它可以在 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);
}