由于包含相互标头,无法在模板化类中成功模板化模板化方法

时间:2012-06-29 02:56:58

标签: c++ templates include

我有一个包含矩阵管理逻辑的类。同时我有一套专门处理矩阵操作操作的重要时间(如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中的包含并保持好友声明的注释,编译器就可以了!

如何解决这个问题?

三江源

2 个答案:

答案 0 :(得分:2)

你可以通过添加几个前向声明来做到这一点......但你甚至可以用更多的代码做得更好:

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>个私有成员,但{{1}你可能不希望这样。

有关声明模板朋友的不同选项的详细说明,请阅读此answer以查看相关问题。

答案 1 :(得分:1)

要使其工作,您需要转发声明该类。它看起来像这样:

文件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

文件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

你的原始声明比我的声明更友好。我只会将友谊授予与该类的类型名匹配的函数。