带有映射声明的 C++ 模板参数

标签 c++ templates stl map

这段代码有什么问题:

标题:

#include <map>

using namespace std;

template<class T>
class ValueCollection
{
public:
    ValueCollection(void);

    int getValueCount(void);

    map<string, T> Values;
};

实现:

#include "ValueCollection.h"

ValueCollection<class T>::ValueCollection(void)
{
}

int ValueCollection<class T>::getValueCount(void)
{
    return Values.size();
}

测试:

#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);
}

这是错误:

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

最佳答案

几个问题。

最直接的编译器错误是由类模板成员函数实现中的语法错误引起的。您必须在类模板成员的定义前加上 template 关键字。即:

template<class T> ValueCollection<T>::ValueCollection(void)
{
}

template<class T> int ValueCollection<T>::getValueCount(void)
{
    return Values.size();
}

还有另一个问题,随着程序的增长,这个问题只会在以后变得明显。您不能在一个文件中定义模板函数或类 Translation Unit并在其他地方使用它们。编译器必须在每个翻译单元中提供完整的定义。

通常,实现这一点的方法是直接在头文件中定义模板函数,就在它们被声明的地方。在你的情况下:

template<class T>
class ValueCollection
{
public:
    ValueCollection(void)
    {
    }

    int getValueCount(void)
    {
        return Values.size();
    }

    map<string, T> Values;
};

这只是实现这一目标的一种方式——还有其他方式。另一种方法是使用所谓的“inclusion method”:

ValueCollection.h

template<class T>
class ValueCollection
{
public:
    ValueCollection(void);

    int getValueCount(void);

    map<string, T> Values;
};

#include "ValueCollection.hpp:

ValueCollection.hpp

template<class T> ValueCollection<T>::ValueCollection(void)
{
}

template<class T> int ValueCollection<class T>::getValueCount(void)
{
    return Values.size();
}

还有一种方法是为每个想要使用模板的翻译单元提供一个新的定义,但这非常不常见。 (事实上​​,在我 15 年的 C++ 编程生涯中,我从未这样做过)

关于带有映射声明的 C++ 模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8272097/

相关文章:

c++ - 在类中强制可变参数模板成员函数实例化

javascript - 在 Meteor JS 中动态加载多个模板?

c++ - 为什么 std::distance() for std:list<int>::iterator 在 last 在 first 之前不返回负数?

c++ - 在新行上使用 clang-format 的右括号

用于自动 getter-setter 方法的 C++ 类模板 - 好的/坏的做法?

c++ - 转发函数指针

c++ - 确定与 std::function<R(T1,T2)> 兼容的函数类型集的规则?

c++ - 如果您要从队列中弹出对象,可以从队列中取出 "Move"对象吗?

xCode 4.2 突然对 STL 一无所知

c++ - Qt 在信号/槽中使用 boost::shared_ptr