简体   繁体   English

C ++模板,传递带有参数化返回类型的函数指针

[英]C++ templating, passing a function pointer with a parameterized return type

I want to parameterize the return value of a function to match the return value of a function pointer I pass it. 我想参数化函数的返回值以匹配我传递给它的函数指针的返回值。 I've only dealt with java generics before, so there's a good chance I'm completely missing something here. 我以前只处理过Java泛型,所以很有可能我在这里完全错过了一些东西。

the function looks like: 该函数如下所示:

<in header>
template <typename T> static T getItems(const char* xpath, T (*getThings)(xpath_node_set*));

<in body>
template <typename T>
T XMLAdapter::getItems(const char* cpath, T(*getThings)(xpath_node_set*)){
    return getThings(head.select_nodes(path));
}

and the function i'm passing into it looks like this: 我传递给它的函数如下所示:

size_t handler(xpath_node_set* in){
    return in->size();
}

And the error i'm getting is: 我得到的错误是:

Error   1   error LNK2019: unresolved external symbol \
"public: static unsigned int __cdecl XMLAdapter::getItems<unsigned int>(char const *,unsigned int (__cdecl*)(class pugi::xpath_node_set *))" (??$getItems@I@XMLAdapter@@SAIPBDP6AIPAVxpath_node_set@pugi@@@Z@Z) \
 referenced in function _wmain  C:\Users\Adam\SkyDrive\Documents\proj\ray\ray\ray.obj   ray

What gives? 是什么赋予了?

remove the static from the prototype, it makes your function file local (ie invisible to other TUs). 从原型中删除static元素,它将使您的功能文件成为本地文件(即,其他TU不可见)。

Generally the function template definition should appear in the header, not a separate .cpp file. 通常,功能模板定义应出现在标题中,而不是单独的.cpp文件。

Template functions need to be fully implemented (not just declared) in the header or you'll hit linker errors like this, if your caller and the template function are not in the same .cpp file. 模板函数需要在标头中完全实现(而不只是声明),否则,如果调用者和模板函数不在同一个.cpp文件中,则会遇到此类链接器错误。

Think about it this way: When you run the compiler on your code, you're actually compiling a separate .obj file for every single .cpp file. 这样考虑:在代码上运行编译器时,实际上是为每个.cpp文件编译一个单独的.obj文件。 From the point of view of the compiler, these are completely independent black boxes. 从编译器的角度来看,它们是完全独立的黑匣子。 Every .cpp file could be compiled in parallel, and there are zero dependencies between them. 每个.cpp文件都可以并行编译,并且它们之间的依赖性为零。 The only dependcies are function declarations (specified in headers) which say "yeah, yeah...someone else is implementing this, let the linker complain if it can't find it." 唯一的依赖关系是函数声明(在标头中指定),其中说:“是的,是的...其他人正在实现此声明,如果链接器找不到它,则让链接器抱怨。”

When you have a template function, what you're really making is a recipe for how to make a function. 当您拥有模板功能时,您真正要做的就是如何制作功能的秘诀。 If you have Foo<T> and you want to call it with int's and with string's, there are literally two generated functions that are completely symbolically different in your final binary: Foo<int> and Foo<string>. 如果您有Foo <T>并想用int和string来调用它,那么实际上在最终二进制文件中,有两个生成的函数在符号上完全不同:Foo <int>和Foo <string>。

That said, if you have your implementation of your template function in a separate .cpp file from someone who is trying to call a specialized version of it, they have no way to "cook" a new version of that function with whatever template arguments they are supplying. 就是说,如果您将模板函数的实现与试图调用它的专用版本的人放在单独的.cpp文件中,则他们将无法使用他们使用的任何模板参数来“烹饪”该函数的新版本正在供应。 All they have is a header that says "Foo<T> is a function someone else implemented" to appease the linker. 他们只有一个标头,上面写着“ Foo <T>是其他人实现的功能”,以安抚链接程序。 But your TemplateImplementation.cpp has no way of knowing that it should have generated a Foo<int> and a Foo<string>. 但是您的TemplateImplementation.cpp无法知道应该生成Foo <int>和Foo <string>。

This is why you'll always see template libraries shipped as header-only libraries. 这就是为什么您总是会看到模板库作为仅标头库提供的原因。 No one could ship you a lib with compiled template functions if they wanted to, because they can't generate the functions until you have called specific versions. 如果有人愿意,没有人会向您提供带有已编译模板函数的库,因为它们只有在您调用特定版本后才能生成这些函数。

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

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