我有一个我提供的课程,我真的不想改变,但我确实想扩展。我是一个模式和模板新手,试验了应用于模板类的Decorator模式。 Template类包含另一个类中的指向成员的指针(如果我理解正确的语义)。指向成员的指针是XML istream的反序列化程序。类型“T”是要反序列化的XML文档的类型。
template <typename T> class B {
public:
typedef std::auto_ptr<T> MYFUN(
std::istream&, const std::string&, const std::string& );
public:
B<T>( MYFUN* p );
private:
MYFUN *fptr;
std::string aString1;
std::string aString2;
};
在阅读http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5之后,typedef对我来说很奇怪,然而这个类看起来效果很好。提供的头文件中没有任何额外的#defines,所以这对我来说有点神秘。
现在我尝试扩展它,作为Decorator,因为我想对MYFUN返回的auto_ptr对象做更多的工作:
template <typename T>
class D : public class B<T>
{
D( B<T>::MYFUN *fPtr, B<T> *providedBase ); //compiler complaint
//Looks like B
private:
B* base_;
};
template <typename T>
D<T>::D( B<T>::MYFUN *p, B<T> *base ) //compiler complaint
:
B<T>::B( p ), base_(providedBase)
{ }
在尝试编译时,我会在显示的两行中收到语法投诉。错误就像是“预期的”)在*“。没有关于MYFUN未定义的抱怨。
当我在D中使用与D中相同的签名重新定义指向成员的指针时,即
//change MYFUN to NEWFUN in D)
typedef std::auto_ptr<T> MYNEWFUN(
std::istream&, const std::string&, const std::string& );
这很有效。我不想为每个我可能做的B / Decorator做这个。我试图更全局地执行typedef,但由于模板参数未定义而无法正确获取语法。
答案 0 :(得分:1)
B中MYFUN typedef的定义是通过私有可见性完成的。 D将无法访问它。如果您将其更改为受保护或公开,那么它是否有效?
template <typename T> class B {
protected:
typedef std::auto_ptr<T> MYFUN(
std::istream&, const std::string&, const std::string& );
...
};
答案 1 :(得分:0)
我看到的问题是B :: MYFUN是私有 typedef。
因此,任何继承类都无法访问它。
将其更改为:
template <typename T> class B
{
public:
typedef std::auto_ptr<T> MYFUN( std::istream&, const std::string&, const std::string& );
public:
B<T>( MYFUN* p );
private:
MYFUN *fptr;
std::string aString1;
std::string aString2;
};
答案 2 :(得分:0)
编译错误是由于编译器无法告诉您正在讨论类型的事实。
尝试:
D( typename B<T>::MYFUN *fPtr, B<T> *providedBase );
和
template <typename T>
D<T>::D( typename B<T>::MYFUN *p, B<T> *base )
请参阅:the templates section of the C++ FAQ Lite以获取有关为什么需要这样做的更多详细信息,但总结是因为模板特化的可能性,编译器无法确定B<T>::MYFUN
实际上是提到一种类型。