繁体   English   中英

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

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

我想参数化函数的返回值以匹配我传递给它的函数指针的返回值。 我以前只处理过Java泛型,所以很有可能我在这里完全错过了一些东西。

该函数如下所示:

<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));
}

我传递给它的函数如下所示:

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

我得到的错误是:

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

是什么赋予了?

从原型中删除static元素,它将使您的功能文件成为本地文件(即,其他TU不可见)。

通常,功能模板定义应出现在标题中,而不是单独的.cpp文件。

模板函数需要在标头中完全实现(而不只是声明),否则,如果调用者和模板函数不在同一个.cpp文件中,则会遇到此类链接器错误。

这样考虑:在代码上运行编译器时,实际上是为每个.cpp文件编译一个单独的.obj文件。 从编译器的角度来看,它们是完全独立的黑匣子。 每个.cpp文件都可以并行编译,并且它们之间的依赖性为零。 唯一的依赖关系是函数声明(在标头中指定),其中说:“是的,是的...其他人正在实现此声明,如果链接器找不到它,则让链接器抱怨。”

当您拥有模板功能时,您真正要做的就是如何制作功能的秘诀。 如果您有Foo <T>并想用int和string来调用它,那么实际上在最终二进制文件中,有两个生成的函数在符号上完全不同:Foo <int>和Foo <string>。

就是说,如果您将模板函数的实现与试图调用它的专用版本的人放在单独的.cpp文件中,则他们将无法使用他们使用的任何模板参数来“烹饪”该函数的新版本正在供应。 他们只有一个标头,上面写着“ Foo <T>是其他人实现的功能”,以安抚链接程序。 但是您的TemplateImplementation.cpp无法知道应该生成Foo <int>和Foo <string>。

这就是为什么您总是会看到模板库作为仅标头库提供的原因。 如果有人愿意,没有人会向您提供带有已编译模板函数的库,因为它们只有在您调用特定版本后才能生成这些函数。

暂无
暂无

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

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