Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/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_Visual C++_Friend Function - Fatal编程技术网

C++ 与模板类中的友元函数链接错误

C++ 与模板类中的友元函数链接错误,c++,templates,visual-c++,friend-function,C++,Templates,Visual C++,Friend Function,使用自制的复杂类时,我有一个链接问题 类别定义: template<class T> class Complex { public: Complex(const T real = 0, const T imag = 0); Complex(const Complex<T>& other); ~Complex(void) {}; Complex<T> operator*(const Complex<T>&am

使用自制的复杂类时,我有一个链接问题

类别定义:

template<class T>
class Complex
{
public:
    Complex(const T real = 0, const T imag = 0);
    Complex(const Complex<T>& other);
    ~Complex(void) {};

    Complex<T> operator*(const Complex<T>& other) const;
    Complex<T> operator/(const Complex<T>& other) const;
    Complex<T> operator+(const Complex<T>& other) const;
    Complex<T> operator-(const Complex<T>& other) const;

    friend void operator*=(const Complex<T>& z,const Complex<T>& other);
    friend void operator/=(const Complex<T>& z,const Complex<T>& other);
    friend void operator+=(const Complex<T>& z,const Complex<T>& other);
    friend void operator-=(const Complex<T>& z,const Complex<T>& other);
    void operator=(const Complex<T>& other);

    friend T& real(Complex<T>& z);
    friend T& imag(Complex<T>& z);
    friend T abs(Complex<T>& z);
    friend T norm(Complex<T>& z);
private:
    T real_;
    T imag_;
};
模板
阶级情结
{
公众:
复数(常数T实=0,常数T imag=0);
综合体(康斯特综合体和其他);
~Complex(void){};
复数运算符*(常数复数和其他)常数;
复数运算符/(常数复数和其他)常数;
复数运算符+(常数复数和其他)常数;
复数运算符-(常数复数和其他)常数;
friend void运算符*=(常数复数和z、常数复数和其他);
friend void运算符/=(常数复数和z、常数复数和其他);
friend void运算符+=(常数复数和z、常数复数和其他);
friend void运算符-=(常数复数和z、常数复数和其他);
void运算符=(const Complex和其他);
friend T&real(Complex&z);
友人T&imag(综合体&z);
friend T abs(Complex&z);
友元T范数(复数&z);
私人:
不真实;
T imag_;
};
abs的实施:

template<class T>
T abs(Complex<T>& z)
{
    return sqrt(z.real_*z.real_ + z.imag_*z.imag_);
}
模板
T abs(复合型和z型)
{
返回sqrt(z.real_*z.real_*z+z.imag_*z.imag_*z);
}

我使用函数abs如下:
if(abs(z)函数声明为

template <typename T>
class Complex {
    // ...
    friend T abs(Complex<T>& z);
    // ...
};
模板
阶级情结{
// ...
friend T abs(Complex&z);
// ...
};
不是函数模板!它看起来有点像,因为它嵌套在类模板中,但这还不够。下面是您可能要编写的内容:

template <typename T> class Complex;
template <typename T> T abs(Complex<T>&);


template <typename T>
class Complex {
    // ...
    friend T abs<T>(Complex<T>& z);
    // ...
};
模板类复合体;
模板T abs(复合物&);
模板
阶级情结{
// ...
friend T abs(Complex&z);
// ...
};

或者,您可以实现
abs()
当声明它为
friend

时,声明和定义是否在同一个文件中?是的,声明和定义在同一个文件中。是的!这正是我需要的修复方法。我不太理解将
abs
而不是
abs
放在后面的逻辑。无论如何,我在做这件事时会记住这种细节g templates.谢谢。@lucas92:逻辑很简单:如何将一系列非模板的函数声明为类模板的朋友?答案是:与您编写它的方式完全相同!使用答案中的符号可以使函数模板的特定实例化成为朋友。您可以编写
模板朋友的abs(Complex&);
但这会使函数模板
abs()
的所有实例化成为
Complex
的朋友。
template <typename T> class Complex;
template <typename T> T abs(Complex<T>&);


template <typename T>
class Complex {
    // ...
    friend T abs<T>(Complex<T>& z);
    // ...
};