“expected initializer before '<' token” 尝试模板成员特化之前需要初始化程序

3

我将尝试在模板类内定义模板成员。

以下是头文件片段:

template <typename Type>
class Queue
{
private:
// class scope definitions
    // Node is a nested structure definition local to this class
    struct Node {Type item; struct Node* next;};
    enum {Q_SIZE = 10};
    template <typename Type2> class DeepCopy // template member
    {
    public:
        void docopy(Type2& d, const Type2& s);
    };
...

所以,模板成员已经定义,但我想为docopy方法进行显式特化,以便在类型为指针时进行深拷贝。我将在头文件中放置另一个片段,其中包含方法模板和特化:

// template member
template <typename Type>
    template <typename Type2>
void Queue<Type>::DeepCopy<Type2>::docopy(Type2& d, const Type2& s)
{
    d = s;
}

// template member specialization for pointers
template <typename Type>
    template <typename Type2>
void Queue<Type*>::DeepCopy<Type2*>::docopy(Type2* d, const Type2* s)
{
    if (s)
        d = new (*s);
    else
        d = 0;
}

编译器给出了以下错误提示:在'<'标记之前需要初始化程序。 我无法弄清楚自己做错了什么。有人能帮忙吗?

1
我认为这种方法行不通。你需要为指针类型完全专门化类。你上面的最后一种定义问题在于,“Queue<T*>”是一个不完整的类型。 - jrok
@jrok 是的,从一开始就有缺陷。谢谢澄清。 - Kurospidey
2个回答

2

针对您的示例,您应该:

  1. T* 部分特化 Queue 类。
  2. Queue<T*> 的部分特化中编写结构体 DeepCopy 的定义。
  3. U* 编写 Queue<T*>::DeepCopy 的特化。
  4. 编写函数 Queue<T*>::DeepCopy<U*>::docopy

注意:请勿删除原有的 HTML 标签。

谢谢你的回答。我尽可能地想避免代码重复。也许我应该尝试PiotrNycz的建议,将DeepCopy类模板定义在Queue模板之外。 - Kurospidey
再次问候。在模板作为参数的示例中,为什么要在Queue内定义一个新的模板成员?另外,如果我想在Queue中添加一个成员对象(该对象属于DeepCopy<T>或DeepCopy<T*>类),我该怎么做?我对此有些困惑。 - Kurospidey
@Kurospidey,为什么要用对象?在我的例子中,DeepCopy函数是静态的。我在类中定义了模板结构体,因为你的例子使用了这种方法。我很困惑,为什么在你的Queue类中,DeepCopy结构体是模板结构体,而不是使用模板参数T。 - ForEveR
网站管理员断开了到 Simple example, http://liveworkspace.org/code/f6505e316e15470b7872a5922c24eef7 的链接。它带我们到一个兜售盗版软件的主页... - jww

2
你应该在队列之外编写你的DeepCopy作为顶级模板。只在队列内部使用它。
   template <typename T>
   class Queue { 
      DeepCopy<T> myCopy;
      ....
          myCopy.doCopy(n.item, newItem);

嗨。 :) 我遇到了麻烦。我误解了你之前的想法,显然实现得很糟糕。我现在要尝试一下! - Kurospidey
当我回到电脑前,我会改进我的先前答案。现在我正在使用移动设备编写,写大量代码并不容易。 - PiotrNycz
我对你的方法有问题,或者可能是我没有理解好。由于队列是一个模板,DeepCopy<T>将采用队列中的任何类型,因此如果队列采用指针,则DeepCopy也将采用指针,并将其应用于通用模板T。但是,如果您放置了DeepCopy <T*>,则它始终采用该规范。我错了吗? - Kurospidey
不,所有的魔法都在于例如 Queue<int*> 中使用 DeepCopy<int*>。而对于 DeepCopy<int*>,指针的特化将被采用。只需尝试并确保放置一些 cout<<LINE<<endl 即可。 - PiotrNycz
只是为了确认一下,这个答案是否表示不要将DeepCopy作为Queue的嵌套/成员类,而是在Queue中使用DeepyCopy的组合对象?如果是这样,为什么呢? - Dennis
1
@Dennis 因为在C++中,函数(包括成员函数)不能被部分特化,只有类可以被部分特化。这也导致了如果它们是另一个模板的成员,则无法对成员模板类进行特化。这就是为什么我建议将此成员模板类移动到封闭类之外的原因。 - PiotrNycz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接