如何调用模板方法?

时间:2010-11-24 19:27:59

标签: c++ function templates methods

有很多在线文档解释了如何编写模板方法,但没有太多关于如何调用它们的示例,如何在代码中使用它们。

我有一个这样的模板方法:

VectorConvertor.h

template <class T>
static void AppendToVector(std::vector<T> & VectorToBeAppended,
                           std::vector<T> & VectorToAppend);


VectorConvertor.cpp

template <class T>
void VectorConvertor::AppendToVector(std::vector<T> & VectorToBeAppended,
                                     std::vector<T> & VectorToAppend)
{
    for (std::vector::size_type i=0; i<VectorToAppend.size(); i++)
    {
        VectorToBeAppended.push_back(VectorToAppend.at(i));
    }
}

代码中的使用尝试

std::vector<uint8_t> InputData, OutputData;
// ...
VectorConvertor::AppendToVector(OutputData, InputData);


我编译此代码没有任何错误。但是当我尝试使用这种方法时,我得到以下错误:

  

错误LNK1120:1个未解析的外部

  

错误LNK2019:未解析的外部符号“public:static void __cdecl VectorConvertor :: AppendToVector(class std :: vector&gt;&amp;,class std :: vector&gt;&amp;)”(?? $ AppendToVector @ E @ VectorConvertor @@ SAXAEAV?$ vector @ EV?$ allocator @ E @ std @@@ std @@ 0 @ Z)在函数“public:staticclass std :: vector&gt; __cdecl Utf8 :: WStringToUtf8(class std :: basic_string, class std :: allocator&gt;)“(?WStringToUtf8 @ Utf8 @@ SA?AV?$ vector @ EV?$ allocator @ E @ std @@@ std @@ V?$ basic_string @ _WU?$ char_traits @ _W @ std @@ V'$分配器@ _W @ @@ 2 3 @@ Z)


当我在代码中不使用此方法时,我没有收到任何错误消息。在调用它时我做错了什么?我错过了什么吗?


我正在使用Visual Studio 2010 Express Edition。

5 个答案:

答案 0 :(得分:7)

在C ++中,使用模板时无法在.cpp文件中分隔定义。您需要将定义放在头文件中。参见:

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

答案 1 :(得分:5)

您需要将函数体放在头文件中。请参阅this FAQ

答案 2 :(得分:2)

模板链接可能会变得棘手。但最简单的解决方案通常是:

将所有模板定义放在标题文件中。

在这种情况下,您应该将VectorConverter.cpp的内容移动到VectorConverter.h(或者可能是VectorConverter.h底部的#include "VectorConverter.cpp")。

答案 3 :(得分:0)

除了将模板函数的定义放在标题中,或包含源文件(cpp文件)之外,您还可以为您需要的任何类型显式实例化函数。

答案 4 :(得分:0)

错误是因为尝试在CPP文件中编写模板方法的定义。为了减少链接时间,通常在头文件中编写内联和模板方法的实现(定义)。下面的代码是声明和定义模板方法的正确方法。

<强> VectorConvertor.h

class VectorConvertor
{
    public:
        template <class T>
        static void AppendToVector1(        std::vector<T> & VectorToBeAppended,
                                    const   std::vector<T> & VectorToAppend);

        template <class T>
        static void AppendToVector2(        std::vector<T> & VectorToBeAppended,
                                    const   std::vector<T> & VectorToAppend);

        template <class T>
        static void AppendToVector3(        std::vector<T> & VectorToBeAppended,
                                    const   std::vector<T> & VectorToAppend);


}

template <class T>
void VectorConvertor::AppendToVector1(          std::vector<T> & VectorToBeAppended,
                                        const   std::vector<T> & VectorToAppend)
{
    VectorToBeAppended.reserve(VectorToBeAppended.size() + VectorToAppend.size());
    for (std::vector<T>::size_type i=0; i<VectorToAppend.size(); i++)
    {
        VectorToBeAppended.push_back(VectorToAppend[i]);
    }
}

template <class T>
void VectorConvertor::AppendToVector2(          std::vector<T> & VectorToBeAppended,
                                        const   std::vector<T> & VectorToAppend)
{
    VectorToBeAppended.reserve(VectorToBeAppended.size() + VectorToAppend.size());
    for (std::vector<T>::const_iterator cit=VectorToAppend.cbegin(); cit!=VectorToAppend.cend(); ++cit)
    {
        VectorToBeAppended.push_back(*cit);
    }
}

template <class T>
void VectorConvertor::AppendToVector3(          std::vector<T> & VectorToBeAppended,
                                        const   std::vector<T> & VectorToAppend)
{
    VectorToBeAppended.insert(VectorToBeAppended.end(), VectorToAppend.cbegin(), VectorToAppend.cend());
}

<强> VectorConvertor.cpp

// Nothing to write in the CPP file.

而且,这是如何在代码中使用它:

std::vector<uint8_t> InputData, OutputData;
// ...
VectorConvertor::AppendToVector3(OutputData, InputData);