如何在 C++ 中使好友 class 的好友函数直接访问其私有成员
How to enable a friend class's friend function access its private members directly in C++
我正在写一个稀疏矩阵class,我想通过重载operator<<
来输出稀疏矩阵。
我想知道如何启用 SMatrix (operator<<
) 的友元函数(而不是通过某些接口) 直接访问 TriTuple 的私有数据成员?请注意,SMatrix 同时是 TriTuple 的朋友 class。见代码如下
// tri-tuple term for sparse matrix by the form <row, col, value>
template<typename T>
class TriTuple {
template<typename U> friend class SMatrix;
// enable friend of SMatrix access private members of TriTuple
// declaring like this? feasible in VS2019, but not in gcc
template<typename U>
friend std::ostream& operator<<(std::ostream& os, const SMatrix<U>& M);
private:
size_t _row, _col;
T _val;
public:
//...
};
// sparse matrix
template<typename T>
class SMatrix {
template<typename U>
friend std::ostream& operator<<(std::ostream& os, const SMatrix<U>& M);
private:
size_t _rows, _cols;// # of rows & columns
size_t _terms; // # of terms
TriTuple<T>* _arr; // stored by 1-dimensional array
size_t _maxSize;
public:
//...
};
template<typename U>
std::ostream& operator<<(std::ostream& os, const SMatrix<U>& M)
{
M.printHeader();
for (size_t i = 0; i < M._terms; ++i) {
os << M._arr[i]._row << "\t\t" << M._arr[i]._col << "\t\t" << M._arr[i]._val << '\n';
}
return os;
}
在VS2019(可能是C++17)中可以编译成功 & 运行,但在gcc中编译失败(目前只有c++11可用)。
那是c++标准版的问题吗? (它指的是 "ISO C++ forbids declaration of ..." )我应该如何改进声明?
请参阅下图中的错误消息。
gcc error_msg
提前谢谢你们真棒:-)
此错误与 class SMatrix
的前向声明有关。
尝试转发 declare
template<typename T>
class SMatrix;
在 TriTuple
之上。
上查看
operator<<
中也没有检查空矩阵。我建议你对 gcc 使用 -fsanitize=undefined -fsanitize=address
。
If a friend declaration appears in a local class ([class.local]) and the name specified is an unqualified name, a prior declaration is looked up without considering scopes that are outside the innermost enclosing non-class scope. For a friend function declaration, if there is no prior declaration, the program is ill-formed. For a friend class declaration, if there is no prior declaration, the class that is specified belongs to the innermost enclosing non-class scope, but if it is subsequently referenced, its name is not found by name lookup until a matching declaration is provided in the innermost enclosing non-class scope.
您需要提供 SMatrix
的定义,或者至少在引用它之前进行前向声明:
template <typename U>
class SMatrix;
我正在写一个稀疏矩阵class,我想通过重载operator<<
来输出稀疏矩阵。
我想知道如何启用 SMatrix (operator<<
) 的友元函数(而不是通过某些接口) 直接访问 TriTuple 的私有数据成员?请注意,SMatrix 同时是 TriTuple 的朋友 class。见代码如下
// tri-tuple term for sparse matrix by the form <row, col, value>
template<typename T>
class TriTuple {
template<typename U> friend class SMatrix;
// enable friend of SMatrix access private members of TriTuple
// declaring like this? feasible in VS2019, but not in gcc
template<typename U>
friend std::ostream& operator<<(std::ostream& os, const SMatrix<U>& M);
private:
size_t _row, _col;
T _val;
public:
//...
};
// sparse matrix
template<typename T>
class SMatrix {
template<typename U>
friend std::ostream& operator<<(std::ostream& os, const SMatrix<U>& M);
private:
size_t _rows, _cols;// # of rows & columns
size_t _terms; // # of terms
TriTuple<T>* _arr; // stored by 1-dimensional array
size_t _maxSize;
public:
//...
};
template<typename U>
std::ostream& operator<<(std::ostream& os, const SMatrix<U>& M)
{
M.printHeader();
for (size_t i = 0; i < M._terms; ++i) {
os << M._arr[i]._row << "\t\t" << M._arr[i]._col << "\t\t" << M._arr[i]._val << '\n';
}
return os;
}
在VS2019(可能是C++17)中可以编译成功 & 运行,但在gcc中编译失败(目前只有c++11可用)。 那是c++标准版的问题吗? (它指的是 "ISO C++ forbids declaration of ..." )我应该如何改进声明? 请参阅下图中的错误消息。 gcc error_msg 提前谢谢你们真棒:-)
此错误与 class SMatrix
的前向声明有关。
尝试转发 declare
template<typename T>
class SMatrix;
在 TriTuple
之上。
operator<<
中也没有检查空矩阵。我建议你对 gcc 使用 -fsanitize=undefined -fsanitize=address
。
If a friend declaration appears in a local class ([class.local]) and the name specified is an unqualified name, a prior declaration is looked up without considering scopes that are outside the innermost enclosing non-class scope. For a friend function declaration, if there is no prior declaration, the program is ill-formed. For a friend class declaration, if there is no prior declaration, the class that is specified belongs to the innermost enclosing non-class scope, but if it is subsequently referenced, its name is not found by name lookup until a matching declaration is provided in the innermost enclosing non-class scope.
您需要提供 SMatrix
的定义,或者至少在引用它之前进行前向声明:
template <typename U>
class SMatrix;