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+中的模板问题+;_C++_Templates - Fatal编程技术网

C++ c+中的模板问题+;

C++ c+中的模板问题+;,c++,templates,C++,Templates,可能重复: 这是我的源代码。 在Number.h中 #ifndef NUMBER_H #define NUMBER_H #include <iostream> using std::istream; using std::ostream; template <class T> class Number; template <class T> ostream& operator<<(ostream&, const Number

可能重复:

这是我的源代码。 在
Number.h中

#ifndef NUMBER_H
#define NUMBER_H

#include <iostream>
using std::istream;
using std::ostream;

template <class T> class Number;

template <class T>
ostream& operator<<(ostream&, const Number<T>&);

template <class T>
istream& operator>>(istream&, Number<T>&);

template <class T>
class Number{
public:
    Number(const T &n)  :i(n) {}
    Number()            :i(0) {}
    T& operator+(const Number&rhs) const;
    T& operator-(const Number&rhs) const;
    T& operator*(const Number&rhs) const;
    T& operator/(const Number&rhs) const;
    friend ostream& operator<< <T> (ostream& , const Number<T>&);
    friend istream& operator>> <T> (istream& , Number<T>&);
private:
    T i;
};

#endif
我不知道为什么会有这种情况

undefined reference to `std::istream& operator>><double>(std::istream&,Number<double>&)'
undefined reference to `Number<double>::operator+(Number<double> const&) const'
对'std::istream&operator>>(std::istream&,Number&)的未定义引用
对“Number::operator+(Number const&)const”的未定义引用

错误等等

所有这些成员函数的定义都需要可用于实例化模板的任何翻译单元。设想一个文件包含
Number.h
,并试图使用
Number
。然后,编译器需要为用
T
实例化为
int
Number
生成所有代码。如果只看到
Number.h
,它怎么能做到这一点?它不知道成员函数的定义


修复方法是将成员函数的定义(从
Number.cpp
)放入
Number.h
。或者,有些人喜欢将
Number.cpp
命名为
Number.tpp
,而不是
,在
Number.cpp
中包含“Number.h”
,将
#包含“Number.tpp”
位于
Number.h
的底部-基本上反转包含,以便标题始终包含实现。

使用.hpp作为模板,并且不能返回对临时对象的引用

编号:h

#ifndef NUMBER_H
#define NUMBER_H

#include <iostream>
using std::istream;
using std::ostream;

template <class T> class Number;

template <class T>
ostream& operator<<(ostream&, const Number<T>&);

template <class T>
istream& operator>>(istream&, Number<T>&);

template <class T>
class Number{
        public:
                Number(const T &n)  :i(n) {}
                Number()            :i(0) {}
                T operator+(const Number&rhs) const; // Error Here return T not T&
                T operator-(const Number&rhs) const;
                T operator*(const Number&rhs) const;
                T operator/(const Number&rhs) const;
                friend ostream& operator<< <T> (ostream& , const Number<T>&);
                friend istream& operator>> <T> (istream& , Number<T>&);
        private:
                T i;
};

#include <number.hpp>

#endif
\ifndef编号\u H
#定义数字
#包括
使用std::istream;
使用std::ostream;
模板类编号;
模板
ostream&运算符(istream&,Number&);
模板
班号{
公众:
数字(常数T&n):i(n){}
Number():i(0){}
T运算符+(常量编号&rhs)const;//此处的错误返回T而不是T&
T运算符-(常数编号和rhs)常数;
T运算符*(常数编号和rhs)常数;
T运算符/(常数编号和rhs)常数;
friend ostream&operator>(istream&,Number&);
私人:
TⅠ;
};
#包括
#恩迪夫
数字.hpp

#ifndef NUMBER_HPP
#define NUMBER_HPP

template<class T> 
T
Number<T>::operator+(const Number& rhs) const
{
        return i + rhs.i;
}

template<class T> 
T
Number<T>::operator-(const Number&rhs) const
{
        return i-rhs.i;
}

template<class T> 
T
Number<T>::operator*(const Number&rhs) const
{
        return i*rhs.i;
}

template<class T>
T
Number<T>::operator/(const Number&rhs) const
{
        return i/rhs.i;
}

template<class T>
ostream& operator<<(ostream&os , const Number<T>&rhs)
{
        return os<< rhs.i;
}

template<class T>
istream& operator>>(istream&is , Number<T>&rhs)
{
            return is >> rhs.i;
}

#endif
\ifndef编号\u水电站
#定义水电站的数量
模板
T
编号::运算符+(常量编号和rhs)常量
{
返回i+rhs.i;
}
模板
T
编号::运算符-(常量编号和rhs)常量
{
返回i-rhs.i;
}
模板
T
编号::运算符*(常量编号和rhs)常量
{
返回i*rhs.i;
}
模板
T
编号::运算符/(常数编号和rhs)常数
{
返回i/rhs.i;
}
模板
ostream&operator>rhs.i;
}
#恩迪夫
main.cpp

    #include <iostream>
    #include <number.h>

    int
    main(int, const char**)
    {
        Number<double>  value(1);
        Number<double>  add(3);

        std::cout << value + add << std::endl;
        std::cout << value * add << std::endl;
        std::cout << value - add << std::endl;
        std::cout << value / add << std::endl;
        return 0;
}
#包括
#包括
int
主(整型,常量字符**)
{
数值(1);
数字加(3);

std::也可以在一般未定义的参考文献下描述问题:非常感谢。我是
模板的新手,您能解释一下为什么
#包括“Number.h”吗
在有
模板
@user1668903的情况下更为常见。恐怕我不太理解这个问题。每当你实例化一个模板,例如
Number
,编译器需要能够生成类
Number
,所有出现的
t
都替换为
int
。要做到这一点,它需要能够看到
Number
的所有代码,因此头文件必须同时包含头文件和实现。对不起,我的意思是为什么人们不总是
#在
Number.h
中包含“Number.cpp”
,而不是
#包含“Number.h”
Number.cpp
@user1668903中的
,因为它是一个正常的实现文件(当它不是模板实现时)需要单独编译。例如,如果您有一个未模板化的类
T
,并且有两个文件
T.h
T.cpp
,您将在某个时候编译
T.cpp
,其中必须包含
T.h
中的类定义。如果
T.cpp
不包含
T.h
,则不会编译,因为没有类定义。但是使用模板实现,
Number.cpp
,它不需要单独编译。事实上,它需要包含在使用它的每个翻译单元中。
    #include <iostream>
    #include <number.h>

    int
    main(int, const char**)
    {
        Number<double>  value(1);
        Number<double>  add(3);

        std::cout << value + add << std::endl;
        std::cout << value * add << std::endl;
        std::cout << value - add << std::endl;
        std::cout << value / add << std::endl;
        return 0;
}