在单独的.cpp文件中专门化功能模板

时间:2016-01-09 22:45:46

标签: c++ templates

我为一个非常简单的打印功能编写了一个模板,我把它放在一个自定义函数库中,这些函数都处理控制台IO。

我为特定项目编写了第二个库,这是原始项目的子项。它专门介绍其中一个模板。

我遇到了一个错误(我怀疑)是由于在专门模板声明之前发生的main.cpp中的调用引起的。该错误包含以下行:

 In instantiation of 'static void baseIO::print(S) [with s = std::vector<int>]'

这意味着它调用baseIO::print()而不是specialIO::print()

我尝试将specialIO::print()作为常规函数而不是模板,并在标头中将其声明为正常,但是拒绝了main.cpp对基本模板的访问。

有没有办法让我的专业化在main.cpp中可用而不必声明在那里实现它?

//in main.cpp
#include <vector>
#include "specialIO.h"

main(){
    std::vector<int> myVector;
    specialIO::print(myVector);
    specialIO::print("hello world");
    return 1;
}

//in baseIO_templates.cpp - templates are outside of the baseIO.cpp file because of linker errors
template<typename S>     //primary template
void baseIO::print(S str){
    std::cout << str;
}

//baseIO.h
class baseIO{
public:
    template<typename S> //primary template
    static void print(S str);
}
#include "baseIO_templates.cpp"

//specialIO.cpp
template<>               //specialized template
void static specialIO::print(vector<int> myVector){
    for(int i : myVector){
        baseIO::print(i)
    }
}

//specialIO.h
class uberIO : public baseIO {
    //empty
}

1 个答案:

答案 0 :(得分:0)

调用代码时,编译器必须可以使用所有模板代码。因此,如果您已声明template<T> void SomeFunction(T x); - 那么当您使用SomeFunctionstd::stringfloat调用时,编译器需要知道MyStruct的定义。因为如果直到现在它还不知道类型,编译器就无法找出如何找到正确的实现(或为正确的实现生成代码)...

因此,您不能将模板实例化放在.cpp文件中 - 如果您在头文件中声明它们,则可以将专门化放在.cpp文件中,因此:

class specialIO : public baseIO {
 public:
   template<>void static print<std::vector>(std::vector<int> v);
};

但是如果你把它留空,编译器甚至不会知道有这样的打印功能,所以不能调用它 - 它会尝试将std::vector传递给常规baseIO::print<T> ,这是行不通的,因为它无法做到这一点。