2

このリンクで提案されているように、#include ディレクティブを使用して C++ テンプレート クラスを 2 つのファイルに分割しました -->複数のファイルに広がるテンプレート

両方のファイルで、標準の名前 *.h および *.cpp を使用しました。makefile に *.h を含めました。これは、私が理解しているように、このように分割された両方のファイルが実際にはコンパイラの観点からは 1 つであるためです。通常の *.cpp ファイルをコンパイルする場合と同じコンパイル オプションを設定しました。

ただし、makefile を使用してコンパイルしようとすると、次のエラーが発生します。

Stos.o: file not recognized: File format not recognized
collect2: ld returned 1 exit status
make: *** [program] Error 1

*.h ファイルをコンパイルしたことが原因である可能性があることをどこかで読みました。代わりに何をすべきかわかりません。

ご協力ありがとうございました。

編集

問題をより明確にするために、メイクファイル自体を投稿しています。申し訳ありませんが、名前が英語ではありませんが、この場合は問題ありません。makefile に合うようにエラー メッセージを更新しました。

ここでの提案により、テンプレート ファイルの名前を上記の *.h および *.cpp から *.hpp および *.tpp に変更しました。

CC=g++
CFLAGS=-c -Wall -pedantic -W
COMP= $(CC) $(CFLAGS)

program: Graf.o wgraf.o wnazwe.o menu.o Stos.o TabDyn.o komunikaty.o main.o
    $(CC) Graf.o wgraf.o wnazwe.o menu.o Stos.o TabDyn.o komunikaty.o main.o -o program
Graf.o: graf_struktura/Graf.cpp graf_struktura/Graf.h lifo/TabDyn.hpp lifo/Stos.hpp
    $(COMP) graf_struktura/Graf.cpp -o $@
wgraf.o: wczytywanie_grafu/wczytaj_graf.cpp wczytywanie_grafu/wczytaj_graf.h    graf_struktura/Graf.h lifo/Stos.hpp
    $(COMP) wczytywanie_grafu/wczytaj_graf.cpp -o $@
wnazwe.o: wczytywanie_grafu/wczytaj_nazwe_pliku.cpp    wczytywanie_grafu/wczytaj_nazwe_pliku.h wczytywanie_grafu/komunikaty.cpp 
    $(COMP) wczytywanie_grafu/wczytaj_nazwe_pliku.cpp -o $@
komunikaty.o: wczytywanie_grafu/komunikaty.cpp
    $(COMP) wczytywanie_grafu/komunikaty.cpp
menu.o: menu/menu.cpp graf_struktura/Graf.h
    $(COMP) menu/menu.cpp
main.o: main.cpp wczytywanie_grafu/wczytaj_nazwe_pliku.h    wczytywanie_grafu/wczytaj_graf.h menu/menu.cpp graf_struktura/Graf.h
    $(COMP) main.cpp
#Here is the issue.
Stos.o: lifo/Stos.hpp lifo/Stos.tpp lifo/TabDyn.hpp
    $(COMP) lifo/Stos.hpp -o $@
TabDyn.o: lifo/TabDyn.hpp lifo/TabDyn.tpp
    $(COMP) lifo/TabDyn.hpp -o $@

コンパイラは実際に「Stos.o」を作成しますが、それを「プログラム」に含めることができず、引用されたエラーが発生します。

私の問題がより明確になることを願っています。makefile が洗練されていない場合は申し訳ありません。私はまだメイクファイルの初心者です。ご理解ください。

4

2 に答える 2

4

MyClass.h が次のようになっている場合

#ifndef MYCLASS_H
#define MYCLASS_H
template<typename T>
  struct MyClass
  {
    void f();
  };
#include "MyClass.tcc"
#endif

MyClass.tcc ファイルは次のようになります。

template<typename T>
  void
  MyClass::f(T)
  { }

次に、たとえば main.cpp というファイルでテンプレートを使用するコードは次のようになります。

#include "MyClass.h"

int main()
{
  MyClass<int> m;
  m.f(1);
}

Makefile は次のようになります。

main: main.o
    $(CXX) $^ $(LDFLAGS) -o $@

main.o: main.cpp MyClass.h MyClass.tcc
    $(CXX) $(CXXFLAGS) $< -o $@

makefile はテンプレート ヘッダーをコンパイルするべきではなく、main.cpp ファイルを .o にコンパイルし、ヘッダーを依存関係として一覧表示します。ヘッダーまたはmain.cpp変更のいずれかmain.oが再コンパイルされる場合。ただし、ヘッダーをコンパイルしないでください。

FWIW、私自身のコードでは.cc、ソース ファイル、.hヘッダー、および.tccインライン定義に使用します。GCC はそれ.tccがヘッダー ファイルであるg++ foo.tccことを認識しており、あなたが.

NB すべてのヘッダー依存関係を手動でリストするのではなく、GCC を使用して依存関係をリストする makefile フラグメントを生成main.cppできmain.dますinclude main.d

于 2012-05-21T23:55:00.103 に答える
1

メイクファイルに .h も .cpp も含めないでください。テンプレートを使用するファイルには .h (これには .cpp が含まれます) が含まれ、すべての翻訳単位はテンプレートのすべての関数の (弱い) シンボルになり、ファイルのいずれも Makefile に含まれません。

于 2012-05-21T23:00:39.673 に答える