由于相互标头包含,无法成功地与模板化类中的模板化方法交朋友
Cannot successfully friend a templated method in a templated class because of mutual header inclusion
我有一个包装矩阵管理逻辑的类。同时,我有一套专门用于处理一些重要的时间花费矩阵操作操作(如 LU 分解等)的方法。
该类使用该文件中定义的函数。该文件需要有权访问该类的元素。我需要使这些专业方法成为上述班级的朋友。这导致我在彼此的标题中包含一个标题。
我的问题
我之前描述的情况在这里编码如下。第一个代码是指mat.hpp
。
#ifndef MAT_HPP
#define MAT_HPP
#include "operations.hpp"
namespace nsA {
template <typename T>
// Templated class because matrices can be real or complex
class mat {
// Members...
friend template <typename U>
void exec_lu(const mat<U>& in, const mat<U>& out);
// Members...
} /* class end */
}
#endif
#endif
第二个文件是operations.hpp
#ifndef OPERATIONS_HPP
#define OPERATIONS_HPP
#include "mat.hpp"
namespace nsA {
namespace nsB {
template <typename T>
void exec_lu(const mat<T>& in, const mat<T>& out);
}
}
#endif
问题是编译器开始抱怨。
注意
请考虑一下,如果我在mat.hpp
中注释朋友声明但保留包含,编译器告诉我在"operations.hpp"中未定义mat
类型!
如果还注释包含在mat.hpp
中并保持朋友声明注释,则编译器就可以了!
如何解决这个问题?
谢谢
您只需添加几个前向声明即可做到这一点...但是你甚至可以用更多的代码做得更好:
template <typename T> class mat;
template <typename T> void exec_lu( const mat<T>&, const mat<T>& );
template <typename T>
class mat {
friend void exec_lu<T>( const mat<T>&, const mat<T>& );
};
template <typename T>
void exec_lu( const mat<T>& a, const mat<T>& b ) { ... }
这种方法和你的方法之间的主要区别(除了修复语法限制)是,在这种方法中,exec_lu
的单个实例被授予对mat<T>
的访问权限,特别是需要访问它的实例化。在您的代码中(修复后),exec_lu
的所有特化都可以访问mat
的任何特化(即 exec_lu<int>
可以访问mat<int>
私人成员,但也可以访问mat<double>
......你可能不想这样。
有关声明模板之友的不同选项的详细说明,请阅读相关问题的此答案。
要使其正常工作,您需要转发声明该类。它看起来像这样:
文件mat.hpp:
#ifndef MAT_HPP
#define MAT_HPP
namespace nsA {
template <typename T>
class mat;
namespace nsB {
template <typename T>
void exec_lu(const mat<T>& in, const mat<T>& out);
}
template <typename T>
class mat {
friend void exec_lu(const mat<T>& in, const mat<T>& out);
};
}
#endif
和文件操作.hpp:
#ifndef OPERATIONS_HPP
#define OPERATIONS_HPP
#include "mat.hpp"
namespace nsA { namespace nsB {
template <typename T>
void exec_lu(const mat<T>& in, const mat<T>& out);
}}
#endif
你最初的宣言比我更能表达出友谊。我的只为与类的类型名匹配的函数授予友谊。
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- C++从另一个类访问公共静态向量的正确方法是什么
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 没有为自己的结构调用列表推回方法
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 在类定义之后定义一个私有方法
- 枚举环境变量的惯用C++14/C++17方法
- 由于相互标头包含,无法成功地与模板化类中的模板化方法交朋友