是否可以将模板功能成为模板专业化类的朋友?

时间:2010-12-16 13:07:22

标签: c++ visual-c++ templates codewarrior

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

1 个答案:

答案 0 :(得分:1)

我已经检查了你的代码,并针对两个编译器进行了测试:g ++ - 4.2和clang ++。我没有看到你的朋友声明有任何问题。