int的静态数组发生奇怪的链接器错误

时间:2011-08-20 14:59:29

标签: c++ c++11

我试图用Clang 3.0编译以下代码。 它无法链接,我在这里做错了什么或这是一个编译器错误?

错误如下

  

架构x86_64的未定义符号:
  “__ZN9int_arrayIJLi0ELi1ELi2ELi3ELi4ELi5ELi6ELi7ELi8EEE4listE”   引自:         __ZN9int_arrayIJLi0ELi1ELi2ELi3ELi4ELi5ELi6ELi7ELi8EEE5printEv   在cc-JDTbNl.o ld:找不到架构x86_64的符号

代码如下

#include <iostream>

static const int a[] = {0,1,2,3,4,5,6,7,8};

template<int... Numbers> struct int_array;

template<int... Numbers>
struct int_array {
  int x;
  const static int list[] = {Numbers...};
  static void print() {
    for (const int x : list) {
        std::cout << x <<std::endl;
    }
  }
  static void print2() {
    for (const int x : a) {
        std::cout << x <<std::endl;
    }
  }
};

typedef int_array<0,1,2,3,4,5,6,7,8> array_of_ints;

int main (int argc, const char * argv[])
{
  array_of_ints::print();
  array_of_ints::print2();
  return 0;
}

2 个答案:

答案 0 :(得分:2)

您的代码错误有两个原因

  • 如果不是整数或枚举类型而不是constexpr
  • ,则无法在类中初始化静态数据成员
  • 您错过了int_array<yournumbers>::list的定义。当您使用该成员时,您需要定义它。

这不是一个铿锵的错误。一旦clang得到constexpr支持,然后你再添加一个out类的定义(然后不能有一个初始值),就像你已经提供了一个类)并用const替换constexpr然后代码应该正常工作。


对于普通大众,here is the PR that @James sent to Clang

答案 1 :(得分:1)

我不是c ++ 0x的专家,希望有更多知识渊博的人来到这里......但C ++ 0x是否允许静态成员的类内初始化?如果是这样,clang还没有实现它。如果没有,你不能。 The (almost) standard,9.4.2第3项,表示任何const字面类型都可以初始化;和3.9项目10说int的数组是文字。所以,我猜这是一个clang 3.0的错误,但在可变参数模板的情况下可能会有进一步的规则......

无论如何,按照以下方式更改代码对我有用:

template<int... Numbers>
struct int_array {
  int x;
  const static int list[];
  static void print() ;
};

template<int... Numbers>
const int int_array<Numbers...>::list[]={Numbers...};

template<int... Numbers>
void int_array<Numbers...>::print(){
    for (const int x : list) {
        std::cout << x <<std::endl;
    }
}