我有一个仅供本地使用的类(即,它的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
错误。
有什么建议吗?
答案 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
}