简体   繁体   English

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

[英]Specializing function template in separate .cpp file

I've written a template for a very simple print function, and I've put it in a library of custom functions that all deal with console IO. 我已经为一个非常简单的打印功能编写了一个模板,并将其放在自定义函数库中,这些库都处理控制台IO。

I've written a second library for a specific project, that is a child of the original. 我为特定项目写了第二个库,它是原始库的一个子库。 It specializes one of the templates. 它专门用于模板之一。

I'm running in to an error which (I suspect) is being caused by the call in main.cpp occurring before the declaration of the specialized template. 我遇到一个错误(我怀疑)是由于在专用模板的声明之前发生的main.cpp调用引起的。 The error contains this line: 错误包含以下行:

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

Which means its calling baseIO::print() instead of specialIO::print() 这意味着其调用baseIO::print()而不是specialIO::print()

I tried making specialIO::print() a regular function instead of a template, and declaring it as normal in the header, but that denied main.cpp access to the base template. 我尝试将specialIO::print()用作常规函数而不是模板,并在标头中将其声明为正常,但是拒绝main.cpp访问基本模板。

Is there a way to make my specialization usable in main.cpp WITHOUT having to declare implement it there? 有没有一种方法可以使我的专业化在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
}

All template code must be available to the compiler when the code is called. 调用代码时,所有模板代码都必须对编译器可用。 So if you have declared template<T> void SomeFunction(T x); 因此,如果您已声明template<T> void SomeFunction(T x); - then the compiler will need to know the definition of SomeFunction when you call it with std::string , or float or MyStruct . -然后,当您使用std::stringfloatMyStruct调用SomeFunction时,编译器将需要知道SomeFunction的定义。 Since there is no way the compiler can figure out how to find the right implementation (or generate code for the right implementation) if it didn't know the type until now... 由于编译器目前尚不知道类型,因此无法找到合适的实现方式(或为正确的实现方式生成代码)。

Therefore, you can't put template instantiations in a .cpp file - it is possible to put the specialization in a .cpp file if you declare them in a header-file, so: 因此,您不能将模板实例化放在.cpp文件中-如果在头文件中声明它们,则可以将专业化放在.cpp文件中,因此:

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

But if you leave it empty, the compiler won't even know there is such a print function, so can't call it - it will try to pass the std::vector into the regular baseIO::print<T> , which won't work because it's not capable of doing that. 但是,如果将其保留为空,编译器甚至不会知道有这样的打印功能,因此无法调用它-它会尝试将std::vector传递给常规的baseIO::print<T> ,将无法正常工作,因为它无法执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM