我创建了一个模板类Number。我重载了<<运营商,但我无法让%运营商工作。
template<typename t>
class Number
{
private:
t n;
public:
Number(t a) :n{ a } {};
Number() :n{ t() } {};
friend ostream & operator<<<>(ostream & os, const Number<t>& a);
friend Number<t> operator%(Number<t> a, Number<t> b);
};
template<typename t>
ostream & operator<<<>(ostream & os, Number<t> a)
{
os << a.n;
return os;
}
template<typename t>
Number<t> operator%(Number<t> a, Number<t> b)
{
return Number<t>(a.n % b.n);
}
正如您所见&lt;&gt; in&lt;&lt;运算符定义,为它完成工作。但是,如果我在%运算符定义中使用它,我会得到一个语法错误,如果我不这样做 “1未解决的外部”错误。所以我的问题可以归结为两个问题 - 1.为什么我们需要使用&lt;&gt;使用朋友符号重载操作符? 2.为什么它不能用于%运算符?
答案 0 :(得分:4)
方法1
在类模板的定义之前声明函数。
public static void main(String[] args) {
int[] p = {7,5,3,1,3,5,7};
for (int i=0; i <= 7; i++) {
System.out.print("\n");
for (int k =i; k <= 7; k++) {
k = p[i];
// I'm trying to find a way to print "*"s with array element value
for(int j=i; j <= 7; j++) {
System.out.print("*");
}
}
}
}
定义班级。确保template <typename t> class Number;
template <typename t>
std::ostream & operator<<(std::ostream & os, const Number<t>& a);
template <typename t>
Number<t> operator%(Number<t> a, Number<t> b);
声明使用模板参数。
friend
实现类定义之外的函数。
template <typename t>
class Number
{
private:
t n;
public:
Number(t a) :n{ a } {};
Number() :n{ t() } {};
// This makes sure that operator<< <int> is a friend of Number<int>
// but not of Number<double>
friend std::ostream & operator<< <t>(std::ostream & os, const Number& a);
friend Number operator%<t>(Number a, Number b);
};
http://ideone.com/dx3fC0处的工作代码。
方法2
在类模板定义中实现template <typename t>
std::ostream & operator<<(std::ostream & os, const Number<t>& a)
{
os << a.n;
return os;
}
template <typename t>
Number<t> operator%(Number<t> a, Number<t> b)
{
return Number(a.n % b.n);
}
函数。
friend
http://ideone.com/5PYQnR处的工作代码。
如果template <typename t>
class Number
{
private:
t n;
public:
Number(t a) :n{ a } {};
Number() :n{ t() } {};
friend std::ostream& operator<<(std::ostream & os, const Number& a)
{
os << a.n;
return os;
}
friend Number operator%(Number a, Number b)
{
return Number<t>(a.n % b.n);
}
};
函数不是太复杂,最好使用第二种方法。整体代码结构很简单。如果friend
函数很复杂,那么使用第一种方法并在类定义之外实现它们可能是有意义的。
答案 1 :(得分:1)
在类中“与它交友”之前,您应首先将运算符声明为函数模板。有关如何正确执行此操作的详细信息,请参阅this和this。
我怀疑你operator <<
离开的原因是using namespace std
未在您的问题中显示,它会从operator <<
引入模板<iostream>
声明。
这应该有效:
#include <iostream>
template<typename T>
class Number;
// Declare the operators here.
template<typename T>
std::ostream & operator<<(std::ostream & os, const Number<T>& a);
template<typename T>
Number<T> operator%(Number<T> a, Number<T> b);
template<typename T>
class Number
{
private:
T n;
public:
Number(T a) :n{ a } {};
Number() :n{ T() } {};
friend std::ostream & operator<< <T>(std::ostream & os, const Number& a);
friend Number operator% <T>(Number a, Number b);
};
template<typename T>
std::ostream & operator<<(std::ostream & os, const Number<T>& a /* was Number<T> ==> signature mismatch */)
{
os << a.n;
return os;
}
template<typename T>
Number<T> operator%(Number<T> a, Number<T> b)
{
return Number<T>(a.n % b.n);
}
int main() {
Number<int> a(5);
Number<int> b(6);
auto c = a % b;
std::cout << a << std::endl;
return 0;
}
答案 2 :(得分:0)
在课堂体中定义这些功能,省去麻烦。此外,如果%
的左侧操作数为Number
,则您不必将其设为好友。
#include <iostream>
using std::ostream;
template<typename t>
class Number
{
private:
t n;
public:
Number(t a) :n{ a } {};
Number() :n{ t() } {};
Number operator%(Number rhs)
{
return Number(n % rhs.n);
}
friend ostream & operator<<(ostream & os, Number a)
{
os << a.n;
return os;
}
};
int main()
{
Number<int> n1(4);
Number<int> n2(2);
std::cout << n1 << ' ' << n2 << '\n';
Number<int> n3 = n1 % n2;
std::cout << n3 << '\n';
}
答案 3 :(得分:0)
你可以让朋友操作员成为模板化操作员:
template<typename t>
class Number
{
private:
t n;
public:
Number(t a) :n ( a ){};
Number() :n( t() ) {};
template<typename TT>
friend Number<TT> operator%(Number<TT> a,const Number<TT>& b);
};
template<typename t>
Number<t> operator%(Number<t> a,const Number<t> &b)
{
return Number<t>(a.n % b.n);
}
int _tmain(int argc, _TCHAR* argv[])
{
Number<int> a;
Number<int> b;
Number<int> c = a %b;
return 0;
}
参见关于外向宣言here的解释。