【问题标题】:Template Argument in Template-Class Assignment Operator模板类赋值运算符中的模板参数
【发布时间】:2016-05-28 23:03:56
【问题描述】:

我正在尝试编写一个通用类MyStack 来实现一个堆栈。我的类中有一个模板变量,类型名称为Data。我还重载了= operator 以将现有的MyStack 对象复制到另一个现有的MyStack 对象。因此,我想在复制之前检查两个类对象是否具有相同类型的变量,即,我不希望将float 类型的对象复制到int 类型的对象。完成这项任务的好方法是什么?

MyStack 定义:

template<typename Data>
class MyStack
{
    Data *data;
    int pos;
    int Max;
    MyStack();

    public:

    MyStack(int);
    int push(const Data);
    int push(const Data *,const Data);
    Data pop();
    Data* pop(const int);
    int getMaxSize();
    int currSize();
    int isEmpty();
    void display();
    MyStack(const MyStack &);
    void operator=(const MyStack s);
    ~MyStack();
};

这是运算符重载部分:

template<typename Data>
void MyStack<Data>::operator=(const MyStack s)
{
    cout<<"Copied with operator overloading"<<endl;
    delete[] data;
    data=new Data[s.Max];
    Max=s.Max;
    pos=s.pos;
    for(int i=0;i<=s.pos;i++)
            data[i]=s.data[i];
}

提前致谢。

【问题讨论】:

  • 您不能拥有MyStack 对象,因为MyStack 是模板,而不是类型。这可能是你困惑的根源。
  • 您无需执行任何操作。编译器会帮你检查。
  • 不相关:查找'c++ self-assignment'。

标签: c++ templates overloading


【解决方案1】:

在声明中

void operator=(const MyStack s);

你有很多问题(见overloading special members):

  1. 返回类型应为MyStack&lt;Data&gt; &amp;
  2. s 应该是一个常量引用。
  3. s 应该作为 const 引用的类型也是 MyStack&lt;Data&gt;

请注意,MyStack 不是实际类型。它是一个“类型工厂”。

总体来说应该是这样的

MyStack<Data> &operator=(const MyStack<Data> &s);

这将顺便解决您的问题 - 它只需要对 MyStack 模板的 const 引用实例化为相同的 Data


如果您也想支持来自其他堆栈类型的分配,您可以考虑如下方式:

#include <type_traits>

template<typename Data>
class MyStack
{
...

    template<typename OtherData>
    typename std::enable_if<
        std::is_convertible<OtherData, Data>::value,
        MyStack<Data> &>::type
        operator=(const MyStack<OtherData> &other);
};

这个用途:

【讨论】:

  • 不值得回答,所以作为评论添加:这里描述的行为是默认行为;如果 OP 想要分配 不同 类型的堆栈,那么他们应该定义 template&lt;typename Data, typename T&gt; MyStack&lt;Data&gt;&amp; MyStack::operator=(const MyStack&lt;T&gt;&amp;),而实现这一点可能会很棘手。
  • @AmiTavory 正如你所说,我更改了重载声明,但你能解释一下为什么即使使用之前的声明代码也能正常工作吗?
  • @iksemyonov 我试图完全按照你所说的方式做,但是我如何以这种方式在类中声明原型。
  • @SouravKanta 查看有关其他类型的问题的更新。至于您为什么要构建它的问题-某些编译器(尤其是 Visual C++)在执行语言规则方面有些松懈。
  • 非常感谢@AmiTavory
猜你喜欢
  • 2019-06-30
  • 2011-11-14
  • 2015-01-27
  • 2016-01-04
  • 2016-09-03
  • 2011-05-23
  • 2020-02-28
相关资源
最近更新 更多