提问人:user13840624 提问时间:7/6/2023 最后编辑:user13840624 更新时间:7/6/2023 访问量:75
定义模板类的友元运算符时不一致
Inconsistency when defining friend operators of template class
问:
下面是一个涉及两个友元算子的 MRE 示例: 和 :operator<<
operator-
#include <ostream>
template <typename T>
class container;
template <typename T>
std::ostream operator<<(std::ostream & os, const container<T> & data);
template <typename T>
container<T> operator-(const int & first, const container<T> & second);
template <typename T>
class container
{
public:
container<T> operator-(const container<T> & other);
friend std::ostream operator<< <>(std::ostream & os, const container<T> & data); // this one works
friend container<T> operator- <>(const int & first, const container<T> & second); // error: declaration of 'operator-' as non-function
};
运算符的实际定义不在这里(也不相关)。如注释所示,编译但结果为:operator<<
operator-
g++:
<source>:16:29: error: declaration of 'operator-' as non-function
16 | friend container<T> operator- <>(const int & first, const container<T> & second); // error: declaration of 'operator-' as non-function
| ^~~~~~~~
<source>:16:37: error: expected ';' at end of member declaration
16 | friend container<T> operator- <>(const int & first, const container<T> & second); // error: declaration of 'operator-' as non-function
| ^
| ;
<source>:16:39: error: expected unqualified-id before '<' token
16 | friend container<T> operator- <>(const int & first, const container<T> & second); // error: declaration of 'operator-' as non-function
| ^
咔嚓++:
<source>:16:29: error: friends can only be classes or functions
friend container<T> operator- <>(const int & first, const container<T> & second); // error: declaration of 'operator-' as non-function
^
<source>:16:38: error: expected ';' at end of declaration list
friend container<T> operator- <>(const int & first, const container<T> & second); // error: declaration of 'operator-' as non-function
^
;
2 errors generated.
(非友元)已被声明的事实使该友元成为“非函数”。operator-
operator-
为什么有效而无效?我该如何解决?朋友是否需要额外的模板参数(不是)?operator<<
operator-
operator-
T
operator-
编辑
答:
2赞
Ruh Roh Raggy
7/6/2023
#1
我认为你以不正确的方式宣布了它。
尝试这样做:
template <typename T>
class container;
template <typename T>
std::ostream& operator<<(std::ostream & os, const container<T> & data) { return os; }
template <typename T>
container<T> operator-(const int & first, const container<T> & second) {return second;}
template <typename T>
class container
{
public:
container<T> operator-(const container<T> & other);
template <typename>
friend std::ostream& operator<<(std::ostream & os, const container<T> & data);
template <typename>
friend container<T> operator- (const int & first, const container<T> & second);
};
编辑:
我注意到,如果您更改顺序(先联系操作员)。它编译得很好。 自c++11
c++20
template <typename T>
class container;
template <typename T>
std::ostream operator<<(std::ostream & os, const container<T> & data);
template <typename T>
container<T> operator-(const int & first, const container<T> & second);
template <typename T>
class container
{
public:
friend std::ostream operator<< <>(std::ostream & os, const container<T> & data); // this one works
friend container<T> operator- <>(const int & first, const container<T> & second); // error: declaration of 'operator-' as non-function
// now it compiles
container<T> operator-(const container<T> & other);
};
评论
0赞
user13840624
7/6/2023
你为什么使用 ?我正在关注 en.cppreference.com/w/cpp/language/friend(“模板好友运算符”部分)。我相信定义正确(就像在 cppreference 中一样)。template <typename>
operator<<
0赞
foragerDev
7/6/2023
代码没有问题。OP 的代码与最新版本的 clang 和 gcc 编译器编译良好。可能是一些编译器语法问题。
0赞
Ruh Roh Raggy
7/6/2023
@user13840624,因为这表明您实际上声明了模板友元函数。
0赞
Ruh Roh Raggy
7/6/2023
@foragerDev 我认为这是不正确的。我不认为这与 c++17 有很大关系。而且我不认为编写需要更高语言标准才能编译的代码是好代码。我提供了用 c++11、c++14、c++17 和 c++20 编译的示例。而 OP 只能在 c++20 中编译。它不言自明。
0赞
user13840624
7/7/2023
为什么交换 es 有效?operator-()
上一个:C++ 中的隐藏好友概念
评论
-std=c++20