IUn*_*own 5 c++ templates stl map
这段代码有什么问题:
标题:
#include <map>
using namespace std;
template<class T>
class ValueCollection
{
public:
ValueCollection(void);
int getValueCount(void);
map<string, T> Values;
};
Run Code Online (Sandbox Code Playgroud)
执行:
#include "ValueCollection.h"
ValueCollection<class T>::ValueCollection(void)
{
}
int ValueCollection<class T>::getValueCount(void)
{
return Values.size();
}
Run Code Online (Sandbox Code Playgroud)
测试:
#include "ValueCollection.h"
TEST(ValueCollection_TestCases, Default_Constructor_MapIsEmpty)
{
ValueCollection<int>* target = new ValueCollection<int>;
int expected = 0;
int actual = target->getValueCount();
ASSERT_EQ(expected, actual);
}
Run Code Online (Sandbox Code Playgroud)
这是错误:
Error 1 error C2079: 'std::_Pair_base<_Ty1,_Ty2>::second' uses undefined class 'T' c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility 167 1 Refactor01
Run Code Online (Sandbox Code Playgroud)
有几个问题。
最直接的编译器错误是由类模板成员函数实现中的语法不正确引起的。您必须在类模板成员的定义前面加上关键字template。以机智:
template<class T> ValueCollection<T>::ValueCollection(void)
{
}
template<class T> int ValueCollection<T>::getValueCount(void)
{
return Values.size();
}
Run Code Online (Sandbox Code Playgroud)
还有另一个问题,随着程序的增长,这个问题才会变得明显。您不能在一个翻译单元中定义模板函数或类并在另一个翻译单元中使用它们。编译器必须在每个翻译单元中提供完整的定义。
通常,实现此目的的方法是直接在头文件中声明模板函数的位置定义模板函数。在你的情况下:
template<class T>
class ValueCollection
{
public:
ValueCollection(void)
{
}
int getValueCount(void)
{
return Values.size();
}
map<string, T> Values;
};
Run Code Online (Sandbox Code Playgroud)
这只是实现这一目标的一种方法——还有其他方法。另一种方法是使用所谓的“包含法”:
template<class T>
class ValueCollection
{
public:
ValueCollection(void);
int getValueCount(void);
map<string, T> Values;
};
#include "ValueCollection.hpp:
Run Code Online (Sandbox Code Playgroud)
template<class T> ValueCollection<T>::ValueCollection(void)
{
}
template<class T> int ValueCollection<class T>::getValueCount(void)
{
return Values.size();
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是为每个想要使用模板的翻译单元提供新的定义,但这将是非常不寻常的。(事实上,我15年的C++编程生涯中从来没有这样做过)