1

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

これはおそらくリンカーの基本的な誤解であるため、私はそれを本当に単純に保ちます。

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

どんな助けでもいただければ幸いです!

4

1 に答える 1

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

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

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

于 2012-05-08T18:36:41.360 に答える