代码之家  ›  专栏  ›  技术社区  ›  hkBattousai

如何调用模板方法?

  •  6
  • hkBattousai  · 技术社区  · 15 年前

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

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

    矢量转换器.h

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


    矢量转换器.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\u cdecl VectorConvertor::AppendToVector(类std::vector>,类std::vector>)”(??$AppendToVector@E@VectorConvertor@@saxaev?$vector@EV?$allocator@E@std@@std@@0@Z)在函数“public:staticclass std::vector>\u cdecl Utf8::WStringToUtf8(class std::basic_string,class std::allocator>)”中引用(?WStringToUtf8@Utf8@SA?AV?$vector@EV?$allocator@E@std@@std@V?$基本字符串@u WU?$char_traits@W@std@V?$allocator@@分配程序W@2@3@Z)


    当我在代码中不使用此方法时,不会收到任何错误消息。我叫它的时候做错了什么?我遗漏了什么吗?


    我正在使用Visual Studio 2010速成版。

    5 回复  |  直到 12 年前
        1
  •  7
  •   Nathan S.    15 年前

    在C++中,在使用模板时不能分离.CPP文件中的定义。您需要将定义放在头文件中。见:

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

        2
  •  5
  •   Matt K    15 年前

    您需要将函数体放在头文件中。见 this FAQ .

        3
  •  2
  •   aschepler    15 年前

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

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

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

        4
  •  0
  •   BЈовић    15 年前

    除了将模板函数的定义放在头中,或者包括源文件(cpp文件),您还可以显式地为所需的任何类型实例化函数。

        5
  •  0
  •   hkBattousai    9 年前

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

    矢量转换器.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());
    }
    

    矢量转换器.cpp

    // Nothing to write in the CPP file.
    

    下面是如何在代码中使用它:

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