模板化 Class 好友运算符成员函数
Templated Class Friend Operator Member Function
我试图在模板化 class 中获取友元函数进行编译,但错误消息和警告我不明白。我已经对这个问题进行了演示。我得到的错误是:
prog.cpp:8:57: error: non-class, non-variable partial specialization C operator+(const B& lhs, const C& rhs);
prog.cpp:15:59: warning: friend declaration 'C operator+(const B&, const C&)' declares a non-template function [-Wnon-template-friend]
friend C operator+(const B& lhs, const C& rhs);
prog.cpp:15:59: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
#include <iostream>
using namespace std;
template<typename A, typename B>
class C;
template<typename A, typename B>
C<A, B> operator+<A, B>(const B& lhs, const C<A, B>& rhs);
template<typename A, typename B>
struct C
{
A val_;
C operator+(const C& other) const;
friend C<A, B> operator+(const B& lhs, const C<A, B>& rhs);
};
template<typename A, typename B>
C<A, B> C<A, B>::operator+(const C<A, B>& other) const
{
C<A, B> c;
c.val_ = this->val_ + other.val_;
return c;
}
template<typename A, typename B>
C<A, B> operator+(const B& lhs, const C<A, B>& rhs)
{
C<A, B> c;
c.val_ = lhs + rhs.val_;
return c;
}
int main()
{
C<string, char> c0,c1;
c0.val_ = " C0 ";
c1.val_ = " C1 ";
cout << "Stuct:" << (c0 + c1).val_ << '\n';
cout << "Friend:" << ('~' + c1).val_ << endl;
return 0;
}
此声明:
template<typename A, typename B>
C<A, B> operator+<A, B>(const B& lhs, const C<A, B>& rhs);
...因为 operator+
和 (
之间的 <A,B>
是错误的,我真的不知道你想在这里做什么。如果你要专门化一个模板化的operator+
,你会使用这种形式,但你不在这里,你是重载一个。
这个声明应该是:
template<typename A, typename B>
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs);
那么你应该在你的 friend
声明中明确指定你想要一个专门的版本:
friend C<A,B> operator+<>(const B& lhs, const C<A,B>& rhs);
你需要把它放在你的 operator+
之前,否则编译器会认为这是非模板函数的特化。
无论如何,如果您没有真正的理由将代码放在 C
class 之外,我会使用 @Jarod42 解决方案。
您的整个代码应如下所示:
// Declaration of struct C with delayed definition
template <typename A, typename B>
struct C;
// Initial declaration of templated operator+
template <typename A, typename B>
C<A, B> operator+ (const B&, const C<A, B>&);
// Definition of C
template <typename A, typename B>
struct C {
friend C operator+<> (const B&, const C&);
// This must be AFTER the templated operator+
C operator+ (const C&) const;
};
template<typename A, typename B>
C<A, B> C<A, B>::operator+(const C<A, B>& other) const {
}
template<typename A, typename B>
C<A, B> operator+(const B& lhs, const C<A, B>& rhs) {
}
最简单的是在class中内联代码:
template <typename A, typename B>
struct C
{
A val_;
C operator+(const C& other) const
{
C c;
c.val_ = this->val_ + other.val_;
return c;
}
friend C operator+ (const B& lhs, const C& rhs)
{
C c;
c.val_ = lhs + rhs.val_;
return c;
}
};
class中没有内联的代码,需要注意前向声明的声明顺序,奇怪语法<>
:
template <typename A, typename B> struct C;
template <typename A, typename B>
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs);
template <typename A, typename B>
struct C
{
A val_;
friend C<A, B> operator+<> (const B& lhs, const C<A, B>& rhs);
C operator+(const C& other) const;
};
template <typename A, typename B>
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs)
{
C<A, B> c;
c.val_ = lhs + rhs.val_;
return c;
}
template <typename A, typename B>
C<A, B> C::operator+(const C<A, B>& other) const
{
C<A, B> c;
c.val_ = this->val_ + other.val_;
return c;
}
我试图在模板化 class 中获取友元函数进行编译,但错误消息和警告我不明白。我已经对这个问题进行了演示。我得到的错误是:
prog.cpp:8:57: error: non-class, non-variable partial specialization C operator+(const B& lhs, const C& rhs);
prog.cpp:15:59: warning: friend declaration 'C operator+(const B&, const C&)' declares a non-template function [-Wnon-template-friend] friend C operator+(const B& lhs, const C& rhs);
prog.cpp:15:59: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
#include <iostream>
using namespace std;
template<typename A, typename B>
class C;
template<typename A, typename B>
C<A, B> operator+<A, B>(const B& lhs, const C<A, B>& rhs);
template<typename A, typename B>
struct C
{
A val_;
C operator+(const C& other) const;
friend C<A, B> operator+(const B& lhs, const C<A, B>& rhs);
};
template<typename A, typename B>
C<A, B> C<A, B>::operator+(const C<A, B>& other) const
{
C<A, B> c;
c.val_ = this->val_ + other.val_;
return c;
}
template<typename A, typename B>
C<A, B> operator+(const B& lhs, const C<A, B>& rhs)
{
C<A, B> c;
c.val_ = lhs + rhs.val_;
return c;
}
int main()
{
C<string, char> c0,c1;
c0.val_ = " C0 ";
c1.val_ = " C1 ";
cout << "Stuct:" << (c0 + c1).val_ << '\n';
cout << "Friend:" << ('~' + c1).val_ << endl;
return 0;
}
此声明:
template<typename A, typename B>
C<A, B> operator+<A, B>(const B& lhs, const C<A, B>& rhs);
...因为 operator+
和 (
之间的 <A,B>
是错误的,我真的不知道你想在这里做什么。如果你要专门化一个模板化的operator+
,你会使用这种形式,但你不在这里,你是重载一个。
这个声明应该是:
template<typename A, typename B>
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs);
那么你应该在你的 friend
声明中明确指定你想要一个专门的版本:
friend C<A,B> operator+<>(const B& lhs, const C<A,B>& rhs);
你需要把它放在你的 operator+
之前,否则编译器会认为这是非模板函数的特化。
无论如何,如果您没有真正的理由将代码放在 C
class 之外,我会使用 @Jarod42 解决方案。
您的整个代码应如下所示:
// Declaration of struct C with delayed definition
template <typename A, typename B>
struct C;
// Initial declaration of templated operator+
template <typename A, typename B>
C<A, B> operator+ (const B&, const C<A, B>&);
// Definition of C
template <typename A, typename B>
struct C {
friend C operator+<> (const B&, const C&);
// This must be AFTER the templated operator+
C operator+ (const C&) const;
};
template<typename A, typename B>
C<A, B> C<A, B>::operator+(const C<A, B>& other) const {
}
template<typename A, typename B>
C<A, B> operator+(const B& lhs, const C<A, B>& rhs) {
}
最简单的是在class中内联代码:
template <typename A, typename B>
struct C
{
A val_;
C operator+(const C& other) const
{
C c;
c.val_ = this->val_ + other.val_;
return c;
}
friend C operator+ (const B& lhs, const C& rhs)
{
C c;
c.val_ = lhs + rhs.val_;
return c;
}
};
class中没有内联的代码,需要注意前向声明的声明顺序,奇怪语法<>
:
template <typename A, typename B> struct C;
template <typename A, typename B>
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs);
template <typename A, typename B>
struct C
{
A val_;
friend C<A, B> operator+<> (const B& lhs, const C<A, B>& rhs);
C operator+(const C& other) const;
};
template <typename A, typename B>
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs)
{
C<A, B> c;
c.val_ = lhs + rhs.val_;
return c;
}
template <typename A, typename B>
C<A, B> C::operator+(const C<A, B>& other) const
{
C<A, B> c;
c.val_ = this->val_ + other.val_;
return c;
}