2017-11-08 21 views
2

テンプレートに問題があります&継承。問題のあるコードを私がここに投稿できるものに書き換えました。次のように私のコードは次のとおりです。テンプレート継承:シンボルが見つかりません

///////////////////////////// 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++」のコードですが、私は私のsliding_var_window機能はR.から呼び出し可能にエクスポートされるため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()機能は、私はそれがvoidとして宣言unsigned short戻り値の型を、持っているように見えます:

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

それは普通ですか?

+0

実際に「最小限再現可能な例」にすることはできますか? –

+0

@DirkEddelbuettel Fabianが私にどのように表示されたのか - 大型の無関係のR/Rcppセクションを取り除く方がいいですか、最後にreprexを追加する方がいいですか? –

+0

あなたの 'nmの' U'を言う... | C++ filt'の出力は、既に 'man nm'を参照しているように、すでに煙草銃であった。 –

答えて

1

Iは、int main() { }を追加し、追加オプションなしg++してコンパイルした後、リンカーエラーを再現できます。

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

これはSlider<double>のvtableの仮想方法Slider<double>::save_result()への参照(仮想メソッドテーブル)が存在することを意味リンク時に解決できなかったものです。原因はsave_result()template <class T> class Sliderに宣言していますが、少なくとも定義していません。あなたの例ではSlider<double>::save_result()が使用されることはありませんが、それはvirtualであるため、定義する必要があります(少なくとも普通のC++を使用する場合、私はRについてはわかりません)。そうしないと、リンク中にSlider<double>のvtableを作成できません。

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

(少なくとも私の再現で)リンクエラーが消滅に変更

+0

ありがとう!私はこれを試してみましょう。私の意図は、これをオーバーライドしなければならない仮想メソッドとして宣言することです。もう一つの賢明な選択肢でしょうか? –

+1

私は '= 0;'と考えましたが、 'slider '型の引数を持っているため、 'Slave 'は' Slave'のような '' Slider ''コンパイラエラーです。 'は純粋な(' = 0')仮想メンバ関数を持っています。しかし、引数として渡した場合、 'template void slide(std :: vector xスライダ&s){}'のように、 '= 0;'を使うことができます。 – Fabian

+0

確かに、それは動作します。多くのことを学ぶ... –

関連する問題