1

我有一个课程,我真的不想改变,但我确实想扩展。我是一个模式和模板新手,正在尝试将装饰器模式应用于模板类。模板类在另一个类中包含一个指向成员的指针(如果我正确理解语义的话)。指向成员的指针是 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,所以这对我来说有点神秘。

现在我尝试将它扩展为装饰器,因为我想对 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 中的每个 D/Decorator 都执行此操作。我尝试更全局地执行 typedef,但由于模板参数未定义,无法正确获取语法。

4

3 回答 3

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& );
...
};
于 2009-05-14T01:30:15.237 回答
0

我看到的问题是 B::MYFUN 是私有类型定义。

因此,任何继承类都无法访问它。

将其更改为:

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;
};
于 2009-05-14T01:32:57.163 回答
0

编译错误是由于编译器无法告诉您正在谈论一种类型。

尝试:

D( typename B<T>::MYFUN *fPtr, B<T> *providedBase );

template <typename T>
D<T>::D( typename B<T>::MYFUN *p, B<T> *base )

请参阅:C++ FAQ Lite 的模板部分,了解有关为什么需要这样做的更多详细信息,但总结是,由于模板特化的可能性,编译器无法确定它B<T>::MYFUN实际上是指一种类型。

于 2009-05-14T04:07:02.987 回答