[解决]
所以我有一个编译器/翻译器,用于我正在研究的编程语言
在过去,该项目是不受管理的,我使用了一些聪明(但可能很糟糕)的技巧来编译这个东西,它一切正常并且运行良好。
最近,我获得了CLion学生许可,我爱上了IDE,所以我决定将我的编译器迁移到CLion项目。
现在我遇到了编译问题,链接器会抛出一堆“Undefined Reference”错误。我看过我的包括警卫,包括和其他东西,但我似乎无法找到造成这种情况的原因...
这是链接器给我的输出的一部分
[ 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>)'
Parser.cpp 是一个很长的文件,但这里有一些相关的部分:
#include "Parser.hpp"
namespace Dragoon
{
std::vector<Error_Msg> Parser::parse(Statement stm, std::shared_ptr<AST_Node> par_node, uint level)
{
这是文件的开头,之前的唯一行是与作者,日期,...的评论行 我还省略了解析器的构造函数和启动解析过程的解析方法。这些都在命名空间内但在显示的方法之前。 (显示的方法是抛出错误的方法)
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);
这些是第130到135行(生成错误的那些)
现在, AST_Node.hpp :
#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
和 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 ++ std之外,我没有使用任何外部库。 libs和STL libs。
我在Windows 10上使用g ++ 4.9.3运行CLion 2016.3。
解 我忘了在C ++中你不能将模板的定义/声明分开。感谢axalis回答我的问题
答案 0 :(得分:0)
问题是,您的模板化方法位于* .cpp文件中。这不起作用,因为在编译.cpp文件时,编译器不知道它将被实例化的模板参数。
这个问题有两个基本解决方案:
1)将方法定义与模板声明(推荐)一起放在头文件中
2)在.cpp文件中添加显式模板实例化:
template class Dragoon::AST_Node<Dragoon::For_Node>;
template class Dragoon::AST_Node<Dragoon::For_Body_Node>;
这不是那么推荐的,因为你可以注意到,模板需要为它将要使用的每一组参数显式实例化,这在一般情况下是不实际的(你可能根本不知道 - 如果有的话) else将在未来用作模板参数,需要添加显式实例化。)