2012-05-08 20 views
1

見て回って、いくつかの同様の質問が見つかりましたが、それらのどれも同じではありませんでした。ほとんどはコンストラクタまたはデストラクタと関係していました。この問題は、おそらく、私の錆びたC++リンカのメモリの結果(数年後にそれを取り戻すこと)よりも多いでしょう。ldシンボルが見つかりません

data.h

#pragma once 

namespace test { 
    class Data_V1 { 
    public: 
     // some getters/setters 
     int getData() { return _d; } 
     void setData(int d) { _d = d; } 
    private: 
     // some data 
     int _d; 
    }; 
} 

builder.h

#pragma once 

namespace test { 
    template <class V> 
    class Builder { 
    public: 
     void build(); 
    }; 
} 

builder.cpp

:これはおそらく、リンカーの基本的な誤解があるため

私は本当のシンプルおこう

#include <iostream> 
#include "builder.h" 

namespace test { 
    template<class V> 
    void Builder<V>::build() { 
     std::cout << "Insert building logic" << std::endl; 
    } 
} 

main.cppに

#include "builder.h" 
#include "data.h" 

using namespace test; 

int main(int argc, char* argv[]) { 
    Builder<Data_V1> b; 
    b.build(); 
} 

コンパイル:

g++ -Wall -ansi -pedantic -c builder.cpp 
g++ -Wall -ansi -pedantic -c main.cpp 
g++ -Wall -ansi -pedantic -o main main.o builder.o 

リンクエラー:

Undefined symbols for architecture x86_64: 
    "test::Builder<test::Data_V1>::build()", referenced from: 
     _main in main.o 
ld: symbol(s) not found for architecture x86_64 
collect2: ld returned 1 exit status 

任意の助けをいただければ幸いです!

+0

私はnm builder.oを実行すると、方法 "ビルド"が表示されません理由はわかりません – nknize

答えて

6

すべての翻訳単位でテンプレート定義を表示する必要があります。定義をcppからヘッダーに移動します。あなたが尋ねる前にBuilder.h

#pragma once 

namespace test { 
    template <class V> 
    class Builder { 
    public: 
     void build(); 
    }; 

    template<class V> 
    void Builder<V>::build() { 
     std::cout << "Insert building logic" << std::endl; 
    } 
} 

は、ありません、あなたが事前に可能なすべての専門分野を知っている限り、実装を隠す方法はありません。

テンプレートは、新しいクラスを作成するための一般化された形式を表します。実装が表示されない場合、テンプレートを特殊化しようとすると、コンパイラは生成するコードを認識できません。

+0

ああ...はい...完全な意味があります。本当にありがとう!私が何年も使った言語を再学習しているような気がする。名誉! – nknize

+0

@ruphosqueこれがあなたの質問に答えるなら、あなたはそれを受け入れるべきです。 – juanchopanza

+0

組織感覚を保つため、実装の詳細を別々のヘッダファイルbuilder-inl.hに移し、関数をインライン化しました。その後、builder.h内にbuilder-inl.hファイルを含めました。少なくともこのようにして、インプリメンテーションの詳細を人為的に隠し、コードのメンテナンスのための組織感覚を維持することができます。 – nknize

関連する問題