gpt4 book ai didi

c++ - 模板继承 : Symbol not found

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:07:37 27 4
gpt4 key购买 nike

我在模板和继承方面遇到了问题。我已经将一些有问题的代码缩减为可以在此处发布的代码。我的代码如下:

///////////////////////////// My header.h file
#include <vector>

template <class T>
class Slider {
protected:
std::vector<T> out;
public:
Slider() : out() {}
virtual void save_result();
};

template <class T>
class SlidingVar : public Slider<T> {
public:
SlidingVar() {}
void save_result() {}
};

template <class T>
void slide(std::vector<T> x, Slider<T> s) {}

///////////////////////////// My sliding_sd.cpp file
#include <vector>
#include "headers.h"

void sliding_var_window(std::vector<double> x) {
SlidingVar<double> s;
slide(x, s);
}

虽然上面都是“纯 C++”代码,但我是在 R 包的上下文中执行此操作的,我的 sliding_var_window 函数将导出为可从 R 调用。

上面的编译没问题,但是当 R 使用 dlopen 加载它时,我得到关于 save_result() 函数的 Symbol not found 错误。奇怪的是,在我削减它之前,其他类似的功能工作得很好,但这个不是。这是构建顺序:

==> R CMD INSTALL --preclean --no-multiarch --with-keep.source tsevents

* installing to library ‘/Users/kwilliams/R/library/3.4’
* installing *source* package ‘TSEvents’ ...
** libs
clang++ -std=gnu++11 -I/usr/local/Cellar/r/3.4.2/lib/R/include -DNDEBUG -I"/Users/kwilliams/R/library/3.4/Rcpp/include" -I/usr/local/opt/gettext/include -I/usr/local/opt/readline/include -I/usr/local/include -fPIC -g -O2 -c sliding_sd.cpp -o sliding_sd.o
clang++ -std=gnu++11 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/local/opt/gettext/lib -L/usr/local/opt/readline/lib -L/usr/local/lib -L/usr/local/Cellar/r/3.4.2/lib/R/lib -L/usr/local/opt/gettext/lib -L/usr/local/opt/readline/lib -L/usr/local/lib -o TSEvents.so sliding_sd.o -L/usr/local/Cellar/r/3.4.2/lib/R/lib -lR -lintl -Wl,-framework -Wl,CoreFoundation
installing to /Users/kwilliams/R/library/3.4/TSEvents/libs
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error: package or namespace load failed for ‘TSEvents’ in dyn.load(file, DLLpath = DLLpath, ...):
unable to load shared object '/Users/kwilliams/R/library/3.4/TSEvents/libs/TSEvents.so':
dlopen(/Users/kwilliams/R/library/3.4/TSEvents/libs/TSEvents.so, 6): Symbol not found: __ZN6SliderIdE11save_resultEv
Referenced from: /Users/kwilliams/R/library/3.4/TSEvents/libs/TSEvents.so
Expected in: flat namespace
in /Users/kwilliams/R/library/3.4/TSEvents/libs/TSEvents.so
Error: loading failed

我怀疑这真的与 RRcpp 无关,但这提供了我的构建环境,所以如果有人可以建议一种方法来证明这个问题纯 C++ 工具链,那将是最受欢迎的。

另一个我不明白的花絮 - 当我查看目标文件中定义的符号时,save_result() 函数似乎有一个 unsigned short 返回类型,当我声明它为 void 时:

% nm src/TSEvents.so | c++filt | grep result
0000000000002df0 unsigned short SlidingVar<double>::save_result()
U Slider<double>::save_result()

这正常吗?

最佳答案

我可以在添加 int main() { } 后重现链接器错误并用 g++ 编译没有其他选项:

sliding_sd.cpp:(.rdata$_ZTV6SliderIdE[__ZTV6SliderIdE]+0x8): undefined reference to `Slider<double>::save_result()'

这意味着存在对虚拟方法的引用 Slider<double>::save_result()Slider<double> 的 vtable(虚拟方法表)中在链接期间无法解决。原因是你声明了save_result()template <class T> class Slider但没有定义它(至少在您发布的代码中)。尽管 Slider<double>::save_result()在您的示例中从未使用过,必须定义它(至少在使用普通 C++ 时,我不知道 R),因为它是 virtual .否则 Slider<double> 的 vtable无法在链接期间创建。

当改为

template <class T>
class Slider {
/* ... */
virtual void save_result() { }
};

链接错误消失了(至少在我的复制品中)。

关于c++ - 模板继承 : Symbol not found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47191084/

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