gpt4 book ai didi

函数模板参数的C++模板实例化

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:09:21 24 4
gpt4 key购买 nike

我在使用模板实例化 [*] 时遇到以下问题。

文件foo.h

class Foo
{
public:
template <typename F>
void func(F f)

private:
int member_;
};

文件foo.cc

template <typename F>
Foo::func(F f)
{
f(member_);
}

文件 caller.cc

Foo::func(boost::bind(&Bar::bar_func, bar_instance, _1));

虽然编译正常,但链接器提示 undefined symbol :

void Foo::func<boost::_bi::bind_t...>

如何实例化函数 Foo::func ?因为它需要一个函数作为参数,所以我有点困惑。我尝试在 foo.cc 中添加一个实例化函数,因为我习惯于使用常规的非函数类型:

instantiate()
{
template<> void Foo::func<boost::function<void(int)> >(boost::function<void(int)>);
}

显然,这是行不通的。如果有人能指出正确的方向,我将不胜感激。

谢谢!

[*] 是的,我阅读了 parashift FAQ lite。

最佳答案

这个问题的答案取决于编译器。某些版本的 Sun C++ 编译器会通过构建模板函数实现的缓存来自动处理这个问题,这些实现将在不同的翻译单元之间共享。

如果您使用的是 Visual C++ 和任何其他无法执行此操作的编译器,您不妨将函数定义放在 header 中。

如果 header 包含在多个 .cc 文件中,不必担心重复定义。编译器用特殊属性标记模板生成的方法,以便链接器知道丢弃重复项而不是提示。这就是为什么C++有“一次定义规则”的原因之一。

编辑:上述评论适用于您的模板必须能够链接给定任何类型参数的一般情况。如果您知道客户端将使用的一组封闭类型,则可以通过在模板的实现文件中使用显式实例化来确保它们可用,这将导致编译器生成用于链接的其他文件的定义。但是在一般情况下,如果您的模板需要使用可能只有客户端知道的类型,那么将模板分成头文件和实现文件就没有什么意义了;无论如何,任何客户都需要包括这两个部分。如果您想将客户端与复杂的依赖关系隔离开来,请将这些依赖关系隐藏在非模板函数后面,然后从模板代码中调用它们。

关于函数模板参数的C++模板实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/228036/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com