c++ - 找不到 ld 符号

标签 c++ compiler-construction linker

环顾四周,发现了几个类似的问题,但没有一个是相同的。大多数与构造函数或析构函数有关。这个问题很可能是我生锈的 C++ 链接器内存(几年后恢复)的结果。

我会保持简单,因为这可能是对链接器的基本误解:

数据.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;
   };
}

构建器.h

#pragma once

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

生成器.cpp

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

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

主要.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

如有任何帮助,我们将不胜感激!

最佳答案

模板定义需要对所有翻译单元可见。将定义从 cpp 移动到 header 。

生成器.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;
   }
}

在你问之前,不,除非你事先知道所有可能的特化,否则没有办法隐藏实现。

模板代表了创建新类的通用形式。如果实现不可见,当您尝试专门化模板时,编译器将不知道要生成什么代码。

关于c++ - 找不到 ld 符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10504379/

相关文章:

c++ - 根据条件拆分 STL 列表

compiler-construction - Web Essentials Less 上的导入文件保存不编译主文件

c++ - Intel (windows) c++ 编译器并将其库实现更改为 gcc。可能吗?

c - 从 C 生成机器代码

c++ - TBB 链接器错误如何判断我是否缺少包含或代码是否已过时

c++ - 如何让 VS2008 在 C++ 项目中使用 __cdecl 而不是 __thiscall?

c++ - Visual Studio 2010 或 C/C++ 性能监视器

c++ - 如何在 C++ 中的 MessageBox 上获取用户输入?

c++ - VS2012下头文件修改函数模板时构建不一致

C++组件对象模型