c ++类中的static const:未定义的引用

时间:2013-06-06 08:41:15

标签: c++ linker static-members

我有一个仅供本地使用的类(即,它的cope只是它定义的c ++文件)

class A {
public:
    static const int MY_CONST = 5;
};

void fun( int b ) {
    int j = A::MY_CONST;  // no problem
    int k = std::min<int>( A::MY_CONST, b ); // link error: 
                                            // undefined reference to `A::MY_CONST` 
}

所有代码都位于相同的c ++ 文件中。在Windows上使用VS进行编译时,完全没有问题 但是,在Linux上编译时,我只得到第二个语句的undefined reference错误。

有什么建议吗?

5 个答案:

答案 0 :(得分:18)

std::min<int>的参数都是const int&(不只是int),即引用int。并且您无法传递对A::MY_CONST的引用,因为未定义(仅声明)。

在课堂外的.cpp文件中提供定义:

class A {
public:
    static const int MY_CONST = 5; // declaration
};

const int A::MY_CONST; // definition (no value needed)

答案 1 :(得分:6)

// initialize static constants outside the class

class A {
public:
    static const int MY_CONST;
};

const int A::MY_CONST = 5;

void fun( int b ) {
    int j = A::MY_CONST;  // no problem
    int k = std::min<int>( A::MY_CONST, b ); // link error: 
                                            // undefined reference to `A::MY_CONST` 
}

答案 2 :(得分:3)

解释这里发生的事情:

你在类中声明了static const整数,这个“特性”在这里可以用它作为常量表达式,即。对于本地数组大小,模板非类型参数等。如果编译器想要使用此常量表达式,它必须能够在该转换单元中看到它的值。

9.5 / 3

  

如果非易失性const静态数据成员是整数或枚举类型,则其在类中声明   定义可以指定一个大括号或等于初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式(5.19)。可以在。中声明文字类型的静态数据成员   使用constexpr指定程序进行分类;如果是这样,其声明应指定一个支撑或等于初始化器   其中作为赋值表达式的每个initializer子句都是一个常量表达式。 [注意:两者都有   在这些情况下,成员可能会出现在常量表达式中。 - 尾注] 该成员仍应被定义   在命名空间范围内,如果它在程序中使用了(3.2)并且命名空间范围定义不得   包含初始化程序

odr-used意味着形成对该变量的引用或接受它的地址。

std::min通过引用获取参数,因此它们 odr-used

解决方案:

定义它!

class A
{
    static const int a = 5;
};

const int A::a; //definition, shall not contain initializer

答案 3 :(得分:0)

我的情况很奇怪

template<class T> class Strange {

public:
  static const char gapchar='-';
  };

template<class T> void Strange<T> method1 {
      char tmp = gapchar;
}

template<class T> void Strange<T> method2 {
    char tmp = gapchar;
}

我包括上述课程,已经工作了几年。

我添加了另一种方法,基本上是相同的签名,只是读取了gapchar。

我只为第三种方法得到了未定义的错误,即使我使用了这三种方法。

然后我改变了通过

初始化静态变量的方式

未在类定义中初始化:

static const char gapchar;

template<class T> const char Strange<T>::gapchar='-';

这解决了这个问题。我无法弄清楚为什么旧的方式 在类中初始化int或char类型(允许的唯一两种类型) 定义部分仅停止其中一种方法,而不是其他方法。

答案 4 :(得分:0)

您还可以将const值保存到本地变量。

class A {
public:
    static const int MY_CONST = 5;
};

void fun( int b ) {
    int j = A::MY_CONST;  // no problem
    int k = std::min<int>( A::MY_CONST, b ); // link error: undefined reference to `A::MY_CONST` 
    int l = std::min<int>( j, b);  // works
}