繁体   English   中英

具有STL容器成员的模板类

[英]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.hFoo.cpp foo类使用“ extern”声明, #include _i.h文件用于实现和实例化。

至于语法,在模板实现文件中使用:

template<class Loc, class T>
LocTree<Loc,T>::method(...)
{
  ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM