[英]template class with STL container member
我正在编写一个使用std :: multimap作为成员的模板类,并得到编译错误。
LocTree.h:
#pragma once
#include <map>
template <class Loc, class T>
class LocTree
{
public :
typedef std::multimap<typename Loc, typename T> TreeType;
LocTree( void );
~LocTree( void ) { };
private :
TreeType db;
};
LocTree.cpp:
#include "StdAfx.h"
#include "LocTree.h"
LocTree< class Loc, class T>::LocTree()
{
}
编译错误(来自VC2005):
Error 1 error C2079: 'std::pair<_Ty1,_Ty2>::first' uses undefined class 'Loc' c:\program files (x86)\microsoft visual studio 8\vc\include\utility 53
Error 2 error C2079: 'std::pair<_Ty1,_Ty2>::second' uses undefined class 'T' c:\program files (x86)\microsoft visual studio 8\vc\include\utility 54
我知道我可以将函数定义放在.h中,但我希望将它们分开,如果这样做是合法的。 如何解决这个(可能是新手)问题?
您的构造函数定义应为:
template<class Loc, class T>
LocTree<Loc,T>::LocTree()
{
}
另外,希望将它们分开...-不要-您正在浪费时间。 使它们分开的唯一方法是在您还包括的不同标头中有一个定义。 因此,从技术上讲,它们是分开的,但是实现仍然可见。
两点。 首先是:什么是:
typedef std::multimap<typename Loc, typename T> TreeType;
应该是什么意思? 我看不出有什么typename
在那里做; 我想您只想要:
typedef std::multimap<Loc, T> TreeType;
其次,在类之外定义类模板的成员函数时,语法为:
template <typename Loc, typename T>
LocTree<Loc, T>::LocTree()
{
}
换句话说,您必须重复template<...>
子句。 (无论您在<...>
使用typename
还是class
都是无关紧要的。由于它不必是类,所以我认识的大多数人都喜欢typename
,因为它更接近于它的含义。)
至于将实现分开:C ++中的模板在这方面有些破损。 您无法避免编译器依赖性。 但是,您仍然希望将实现与定义分开。 通常的技术是将模板实现放在单独的文件中(例如.tcc
),并.tcc
文件中包含它。
使模板的实现保持独立不是一件容易的事。
通常,这是无法完成的。 也就是说,在模板化参数可能为“任何”的情况下,无法完成此操作。
对于模板参数的特定有限子集,可以执行此操作,例如,如果您有如下模板:
template< bool B > class Foo;
然后,您可以指定:
extern template class Foo<true>;
extern template class Foo<false>;
这称为“实例化”模板,并向编译器指定存在在其他位置实现的值true和false的实现。
如果模板化参数是类型且限于特定子集,也可以执行此操作。
然后,在编译单元中定义模板实现,然后使用与上面相同但没有单词“ extern”的方式再次实例化模板。
如果您正在创建成员函数来设置数据库存储过程调用的参数值(其中仅允许参数类型的非常有限的子集),那么我已经在生产代码中完成了此操作。 如果您的类型是一个非常有限的子集,那么继续进行操作,如果这有助于解耦代码并隐藏许多实现细节(那么在数据库中完成实现的话,那是非常值得的)。
有一个“介于两者之间”的基础,您可以在另一个标头中提供实现,通常我会看到_i.h
或类似的约定,然后才在实例中实例化模板(包括此标头)。 因此,如果您创建了一个Foo类,则在标头中为Foo.h
和Foo.cpp
foo类使用“ extern”声明, #include
_i.h
文件用于实现和实例化。
至于语法,在模板实现文件中使用:
template<class Loc, class T>
LocTree<Loc,T>::method(...)
{
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.