2016-01-09 32 views
0

我已经为一个非常简单的打印函数编写了一个模板,并且将它放在了一个所有处理控制台IO的自定义函数库中。在单独的.cpp文件中专门设计函数模板

我已经为一个特定的项目编写了第二个库,那是一个原创的小孩。它专门化了其中一个模板。

我遇到了一个错误(我怀疑)是由main.cpp中的调用在专用模板声明之前发生的。错误有这样一行:

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

这意味着它的调用的specialIO::print()baseIO::print()代替

我试图使specialIO::print()普通函数,而不是一个模板,并在头宣布它作为正常的,但否认主.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 
} 
+0

任何特定的原因,为什么你总是复制矢量,而不是通过const ref传递它? – axalis

回答

0

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

因此,您不能将模板实例的.cpp文件 - 这是可能把专业化.cpp文件,如果你在一个头文件声明它们,所以:

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

但如果你把它空,编译器将不即使知道有这样的打印功能,所以不能调用它 - 它会尝试将std::vector传递到常规baseIO::print<T>,这将不起作用,因为它不能这样做。

+0

我怀疑我需要在标题中包含某些内容,但不知道是什么。爱你的解释的彻底性。谢谢! – ISaidWutWut

+0

添加到我的代码,但现在我得到“错误:在非名称空间范围'显式专业化'class specialIO' – ISaidWutWut