2017-01-15 4 views
0

[SOLVED]
私は作業しているプログラミング言語用のコンパイラ/トランスレータを持っています。
これまでプロジェクトは管理されておらず、コンパイルには巧妙な(しかしおそらくひどい)トリックを使いました。
しかし、私はCLion Studentライセンスを取得しました。私はIDEに恋しました。そこで、私は自分のコンパイラをCLionプロジェクトに移行することに決めました。
今、私はコンパイルに問題があります。リンカは、私に「未定義参照」エラーを投げます。私は警備員、含まれており、他のものが含まれる上で、私が見てきたが、私はこれを引き起こしているものを見つけるように見えることはできません...
これは、リンカが私にCMake/g ++リンク時に定義されていない参照エラーが発生する

[ 86%] Linking CXX executable Compiler.exe 
C:/.../Compiler/src/Parser/Parser.cpp:133: undefined reference to `void Dragoon::AST_Node::add_child<Dragoon::For_Node>(std::shared_ptr<Dragoon::For_Node>)' 
C:/.../Compiler/src/Parser/Parser.cpp:134: undefined reference to `void Dragoon::AST_Node::add_child<Dragoon::For_Body_Node>(std::shared_ptr<Dragoon::For_Body_Node>)' 

パーサを与えている出力の一部であります.cppファイルは非常に長いファイルであるが、ここでは関係の部品の一部です:

ファイルの先頭です
#include "Parser.hpp" 

namespace Dragoon 
{ 
    std::vector<Error_Msg> Parser::parse(Statement stm, std::shared_ptr<AST_Node> par_node, uint level) 
    { 

、著者、日付とコメント行される前にのみ行、...
も 私はパーサのコンストラクタとパースを省略したメソッドを呼び出すと、解析プロセスが開始されます。これらは両方ともネームスペース内ですが、表示されるメソッドの前にあります。

#include <string> 
#include <memory> 
#include <vector> 
#include "Node_Classes.h" 
#include "../Constants/Aliases.h" 

#ifndef COMPILER_AST_NODE_HPP 
#define COMPILER_AST_NODE_HPP 

namespace Dragoon 
{ 
    class AST_Node 
    { 
     protected: 
      std::string m_class; 

      std::shared_ptr<AST_Node> m_parent; 

      std::vector<std::shared_ptr<AST_Node>> m_children; 

     public: 
      AST_Node(); 

      AST_Node(std::shared_ptr<AST_Node> m_parent, std::string node_class); 

      std::shared_ptr<AST_Node> get_parent(void); 

      std::shared_ptr<AST_Node> get_child(uint index); 

      int num_children(void); 

      template<typename T> 

      void add_child(std::shared_ptr<T> ch); 

      std::string node_class(void); 

      virtual std::string to_string(void); 

      virtual std::string get_type(void); 

      void print(uint level); 
    }; 
} 

#endif //COMPILER_AST_NODE_HPP 

  par_ptr->add_child(for_node); 
      for_node->add_child(body_node); 
      this->m_current_node = body_node; 

      std::vector<Error_Msg> parse_errors = this->parse(init, for_node, level + 1); 

これらは、(エラーを生成するもの)135を介してライン130であり、AST_Node.hpp(示された方法は、エラーをスローするものです) AST_Node.cpp(別の部分を見たいと思っている場合は、無関係のコードで過負荷にならないようにいくつかの部分を残しておきました。私は質問を更新します)

#include "AST_Node.hpp" 

namespace Dragoon 
{ 

と問題方法:

template<typename T> 

void AST_Node::add_child(std::shared_ptr<T> ch) 
{ 
    this->m_children.push_back(ch); 
} 

次のように私のプロジェクト構造は次のとおりです。

Compiler 
    \_cmake-build-debug (default cmake dir, haven't touched it) 
    \_Example Code (My programming language, will be used to test the compiler) 
    \_src 
     \_Collections (Arrays of constants and such) 
     \_Constants (Things like error codes etc.) 
     \_Lexer (All Lexer-relevant code) 
     \_Parser (All Parser-relevant code, this is where both of the shown files are) 
     \_Symbol Table (Symbol and Function Table) 
     \_Utils (Several utility functions, like concatenating an array to a string etc., A bunch of the other "undef. reference" errors also point here) 
     \_Some C++ code that doesn't really fit in any folder (Error_Msg class for instance) 
     \_CMakeList.txt 

マイCMakeList.txt

cmake_minimum_required(VERSION 3.6) 
project(Compiler C CXX) 

add_definitions(-D_WIN32) 

set(SOURCE_FILES ... 
        "src/Parser/Parser.cpp" 
        ... 
        "src/Parser/AST_Node.cpp" 
        ...) 

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y") 

add_executable(Compiler ${SOURCE_FILES}) 

私が残してきましたその中のファイルの大部分を私が示したファイルは同じ順序です。

私はこのスレッドを経てきた:What is an undefined reference/unresolved external symbol error and how do I fix it?

しかし、私は、私の考えることができる唯一のことは行っていない(つまり、でも、関連性の場合は?)私のソースファイルがリストされている順にチェックされ

これはなぜ起こっているのかについてのヒントがあれば、大歓迎です

私はC++標準以外の外部ライブラリを使用していません。 libsとSTLライブラリ。

私はSOLUTION

のWindows 10上で4.9.3 ++グラムとCLion 2016.3を実行していますが、私はC++でテンプレートの定義/宣言を分離することはできませんことを忘れてしまいました。

答えて

0

問題はあなたのテンプレート化されたメソッドが* .cppファイルにあるということです。これはうまくいきません。なぜなら、.cppファイルがコンパイルされているとき、コンパイラーはインスタンス化されるテンプレートパラメーターを知りません。

1)推奨テンプレート宣言()

2).cppファイルに明示的なテンプレートのインスタンスを追加しますとともに、ヘッダファイルにメソッド定義を入れて:

この問題の二つの基本的なソリューションがあります。 :あなたが気づくことができるよう、テンプレートはあなたがいないかもしれませんが、明示的に、一般的には実用的ではない、それは今までで使用されるパラメータのすべてのセット、(のためにインスタンス化する必要があるためそう、推奨されません

template class Dragoon::AST_Node<Dragoon::For_Node>; 
template class Dragoon::AST_Node<Dragoon::For_Body_Node>; 

偶数将来、テンプレート引数として他のものが使用される場合は、明示的なインスタンス化を追加する必要があります)。

+0

ありがとうございました。私はこれを完全に忘れて、私に思い出させてくれてありがとう。 – shmoo6000

関連する問題