Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 不同类型的运算符_C++_Templates_Operator Overloading - Fatal编程技术网

C++ 不同类型的运算符

C++ 不同类型的运算符,c++,templates,operator-overloading,C++,Templates,Operator Overloading,现在,我正在尝试实现加法和减法运算符,但它不仅能够在向量之间执行运算,还能够使用标量short、long、float、double等。这将是一个元素操作 下面可以看到代码的相关部分,template类的声明和定义实现都在同一个.hpp文件检查问题中,因此似乎没有提供解决方案 // Forward declaration of friend function template<class S, class T> Vector<T> operator +(const S&am

现在,我正在尝试实现加法和减法运算符,但它不仅能够在向量之间执行运算,还能够使用标量short、long、float、double等。这将是一个元素操作

下面可以看到代码的相关部分,template类的声明和定义实现都在同一个.hpp文件检查问题中,因此似乎没有提供解决方案

// Forward declaration of friend function
template<class S, class T>
Vector<T> operator +(const S& scalar, const Vector<T>& vec);

template<class T>
class Vector {
  public:
    Vector(unsigned long length);
    Vector(Vector<T> vec);

    template<class S>
    friend Vector<T> operator +(const S& scalar, const Vector<T>& vec);
    
    template<class S>
    Vector<T> operator +(const S& scalar) const;

    template<class S>
    Vector<T>& operator +=(const S& scalar);

  private:
    unsigned long mLen;
    T* mData;
};

// Constructor
Vector<T>::Vector(const unsigned long length) : mLen(length) {
  mData = new T[mData];

  for(unsigned long i = 0; i < mLen; ++i) {
    mData[i] = T();
  }
}

// Copy constructor
template<class T>
Vector<T>::Vector(Vector<T> vec) {
  mLen = 0;
  mData = nullptr;
  std::swap(mData, vec.mData);
}

// Implementation of the operators
template<class S, class T>
Vector<T> operator +(const S& scalar, const Vector<T>& vec) {
  return vec + scalar;
}

template<class T> template<class S>
Vector<T> operator +(const S& scalar) const {
  Vector<T> result(*this);
  return result += scalar;
}

template<class T> template<class S>
Vector<T>& Vector<T>::operator +(const S& scalar) {
  // mLen is the length of the object (member variable)
  for(unsigned long i = 0; i < mLen; ++i) {
    mData[i] += scalar; // mData is the array holding the values (member variable)
  }

  return *this;
}
我得到以下错误

架构x86_64的未定义符号: 运算符+int常量,向量常量,引用自: _主音中的主音 ld:未找到架构x86_64的符号 clang:错误:链接器命令失败,退出代码为1使用-v查看调用

我正在为这个项目开发XCode 11.3.1

任何见解都是非常受欢迎的。另外,我知道我对模板的理解和对C++的更多了解,但如果你需要更多的信息来获得更好的想法,请告诉我。
提前感谢。

首先,免费函数模板不需要是朋友,因为它不直接访问Vector中的私有成员。它也不需要向前声明。通过使用std::vector使数据不必手动实现,这也可以大大简化

例如:

#include <vector>

template<class T>
class Vector {
public:
    Vector(unsigned long length) :
        mData(length) // create the vector
    {}

    template<class S>
    Vector& operator+=(S scalar) {
        for(auto& v : mData) v += scalar;  // add "scalar" to all elements in the vector
        return *this;
    }

    template<class S>
    Vector operator+(S s) const {
        Vector copy(*this);       // using the implicitly defined copy constructor
        copy += s;                // use the above operator+=
        return copy;
    }

private:
    std::vector<T> mData;
};

template<class S, class T>
Vector<T> operator +(S scalar, const Vector<T>& vec) {
    return vec + scalar;
}

首先,免费函数模板不需要是朋友,因为它不直接访问Vector中的私有成员。它也不需要向前声明。通过使用std::vector使数据不必手动实现,这也可以大大简化

例如:

#include <vector>

template<class T>
class Vector {
public:
    Vector(unsigned long length) :
        mData(length) // create the vector
    {}

    template<class S>
    Vector& operator+=(S scalar) {
        for(auto& v : mData) v += scalar;  // add "scalar" to all elements in the vector
        return *this;
    }

    template<class S>
    Vector operator+(S s) const {
        Vector copy(*this);       // using the implicitly defined copy constructor
        copy += s;                // use the above operator+=
        return copy;
    }

private:
    std::vector<T> mData;
};

template<class S, class T>
Vector<T> operator +(S scalar, const Vector<T>& vec) {
    return vec + scalar;
}


我猜您已经将模板的实现放在cpp文件中了。模板必须在头文件中定义。请将您的问题显示出来。你到底在哪里定义实现运算符函数?@MarekR,不,不幸的是,情况并非如此。我还声明,在这个问题中,声明和实现位于同一个.hpp文件中。不要在类定义之前向前声明操作符+,该类定义将操作符声明为友元。该定义将是模板模板类向量运算符+consts&scalar,constvector&vec{return vec+scalar;}。如果你真的必须向前声明,用同样的方法,但不使用正文。不要使用单个模板关键字将嵌套模板与模板类的模板成员函数组合。请查看不同的签名:Vector operator+const S&scalar,const Vector&vec;vs友元向量运算符+常量S&scalar,Vector vec;。constvector&vec不是Vector-vec。我猜您已经将模板的实现放在cpp文件中了。模板必须在头文件中定义。请将您的问题显示出来。你到底在哪里定义实现运算符函数?@MarekR,不,不幸的是,情况并非如此。我还声明,在这个问题中,声明和实现位于同一个.hpp文件中。不要在类定义之前向前声明操作符+,该类定义将操作符声明为友元。该定义将是模板模板类向量运算符+consts&scalar,constvector&vec{return vec+scalar;}。如果你真的必须向前声明,用同样的方法,但不使用正文。不要使用单个模板关键字将嵌套模板与模板类的模板成员函数组合。请查看不同的签名:Vector operator+const S&scalar,const Vector&vec;vs友元向量运算符+常量S&scalar,Vector vec;。const Vector&vec不是Vector vec。@Harry是的,这是正确的,但是不能执行像return copy+=s;我自己都没用过。我想这是一个品味的问题。@Harry,其实这不仅仅是一个品味的问题。运算符应该有其通常的含义。因为你可以把+=链接起来,如果你的类的用户不能做到这一点,他们会感到惊讶,你应该尽量避免让你的用户感到惊讶:嗯,我从来没有听说过这样做的任何理由,除非它不是严格必要的:p如果你记得你在哪里看到的,让我知道,我很想看看理由:是的,我个人建议继续用惯用的方式来做。谢谢:我可能遗漏了一些我从未想到过的东西,所以最好能发现:@ZaellixA嗯,奇怪,也许你可以用这个部分创建一个新问题,并显示代码和你想做的事?旁注:我刚刚注意到你的代码中有一个bug,这是我使用编译器生成的复制构造函数时没有想到的:mLen=0;应为mLen=vec.mLen;在副本构造函数中。但我想知道它是如何工作的?签名向量依赖于复制构造函数?@Harry是的,没错,但是不能进行链式操作
s类似于返回副本+=s;我自己都没用过。我想这是一个品味的问题。@Harry,其实这不仅仅是一个品味的问题。运算符应该有其通常的含义。因为你可以把+=链接起来,如果你的类的用户不能做到这一点,他们会感到惊讶,你应该尽量避免让你的用户感到惊讶:嗯,我从来没有听说过这样做的任何理由,除非它不是严格必要的:p如果你记得你在哪里看到的,让我知道,我很想看看理由:是的,我个人建议继续用惯用的方式来做。谢谢:我可能遗漏了一些我从未想到过的东西,所以最好能发现:@ZaellixA嗯,奇怪,也许你可以用这个部分创建一个新问题,并显示代码和你想做的事?旁注:我刚刚注意到你的代码中有一个bug,这是我使用编译器生成的复制构造函数时没有想到的:mLen=0;应为mLen=vec.mLen;在副本构造函数中。但我想知道它是如何工作的?签名向量依赖于复制构造函数?