C ++ 0x lambdas的未定义符号?

Posted

技术标签:

【中文标题】C ++ 0x lambdas的未定义符号?【英文标题】:Undefined symbols for C++0x lambdas? 【发布时间】:2010-04-19 03:53:14 【问题描述】:

当我遇到一个绊脚石时,我只是在探索 C++0x 中的一些新东西:

#include <list>
#include <cstdio>
using namespace std;

template <typename T,typename F>
void ForEach (list<T> l, F f) 
    for (typename list<T>::iterator it=l.begin();it!=l.end();++it)
        f(*it);


int main() 
    int arr[] = 1,2,3,4,5,6;
    list<int> l (arr,arr+6);
    ForEach(l,[](int x)printf("%d\n",x););

不编译。我收到大量未定义的符号错误。这是make 的输出:

 i386-apple-darwin9-gcc-4.5.0 -std=c++0x -I/usr/local/include -o func main.cpp
Undefined symbols:
  "___cxa_rethrow", referenced from:
      std::_List_node<int>* std::list<int, std::allocator<int> >::_M_create_node<int const&>(int const&&&) in ccPxxPwU.o
  "operator new(unsigned long)", referenced from:
      __gnu_cxx::new_allocator<std::_List_node<int> >::allocate(unsigned long, void const*) in ccPxxPwU.o
  "___gxx_personality_v0", referenced from:
      ___gxx_personality_v0$non_lazy_ptr in ccPxxPwU.o
  "___cxa_begin_catch", referenced from:
      std::_List_node<int>* std::list<int, std::allocator<int> >::_M_create_node<int const&>(int const&&&) in ccPxxPwU.o
  "operator delete(void*)", referenced from:
      __gnu_cxx::new_allocator<std::_List_node<int> >::deallocate(std::_List_node<int>*, unsigned long) in ccPxxPwU.o
  "___cxa_end_catch", referenced from:
      std::_List_node<int>* std::list<int, std::allocator<int> >::_M_create_node<int const&>(int const&&&) in ccPxxPwU.o
  "std::__throw_bad_alloc()", referenced from:
      __gnu_cxx::new_allocator<std::_List_node<int> >::allocate(unsigned long, void const*) in ccPxxPwU.o
  "std::_List_node_base::_M_hook(std::_List_node_base*)", referenced from:
      void std::list<int, std::allocator<int> >::_M_insert<int const&>(std::_List_iterator<int>, int const&&&) in ccPxxPwU.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [func] Error 1

为什么这不起作用?

【问题讨论】:

不是你遇到的问题,但我认为通过引用而不是值接受函子会更好。 @Ben:通常你想按值取值,因为如果函子是可变的,它仍然可以工作。如果您真的不想制作副本,std::ref 会解决这个问题。 @Austin:std::for_each 也可以。 :P @GMan,嗯,是的,但重点是玩新东西......:D @GMan:如果您在 lambda 中捕获了变量,按值传递不会中断连接吗? @Ben:不。 Lambda 不是可复制分配的,但它们具有隐式生成的复制构造函数(和移动构造函数)。当函数被调用时,它将被复制构造,这也将绑定副本的引用,就像它们在原始 lambda 中一样。 【参考方案1】:

这些是链接错误。您是否缺少 C++ 库?如果您使用i386-apple-darwin9-g++-4.5.0 会怎样?

附:我无法对此进行测试,因为我的 Mac 上有 gcc 4.2.1 (i686-apple-darwin10-gcc-4.2.1) 并得到:

cc1plus: error: unrecognized command line option "-std=c++0x"

【讨论】:

C++0x 支持需要非常新版本的g++。但是您对g++ 而不是gcc 的建议可能一针见血。 如果 gcc 没有将其识别为 C++ 源文件,它将如何进入链接器阶段? 好吧,但是它进入了链接阶段,这可能就是问题所在。使用 gcc 而不是使用 4.5 的 g++ 编译 c++0x 代码时,我得到完全相同的错误。 任何时候你看到Undefined symbols: ... "operator new(unsigned long)",你需要立即想,“我的C++标准库没有被链接进去。它认为我正在构建一个C程序。 " @Dennis:对于大多数程序,编译和链接步骤是单独的命令。您为每个源文件运行一个编译过程,完成后,您获取所有对象并将它们链接起来。虽然gcc 完全能够通过查看后缀在compile 时间告诉它何时提供C++ 源代码,但在编译完成后,在链接之前,此信息将被丢弃,因为所有已编译的文件都会得到后缀相同:.o.

以上是关于C ++ 0x lambdas的未定义符号?的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式 C/C++:现有符号的未定义引用

架构 armv7 的未定义符号:用于外部 C 库

C++ FFT 实现(架构 x86_64 的未定义符号)

架构 x86_64 的未定义符号:C++ OS X 向量

动态加载库的未定义符号“typeinfo”

对符号 glTexImage2D 的未定义引用