据我所知,C ++允许静态常量构件一类的内部,只要它是一个整数类型来定义。
那么,为什么不将下面的代码给我一个链接错误?
#include <algorithm>
#include <iostream>
class test
{
public:
static const int N = 10;
};
int main()
{
std::cout << test::N << "\n";
std::min(9, test::N);
}
我得到的错误是:
test.cpp:(.text+0x130): undefined reference to `test::N'
collect2: ld returned 1 exit status
有趣的是,如果我注释掉调用到std ::分钟,代码编译和链接就好了(即使测试:: N也上一行引用)。
任何想法,以什么回事?
我的编译器是在Linux上的gcc 4.4。
你有几分正确。 你被允许在类声明中初始化静态const的积分,但是这不是一个定义。
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/cplr038.htm
任何想法,以什么回事?
的std ::分钟通过const引用采取它的参数。 如果把他们的价值你没有这个问题,但是,因为你需要一个参考,你还需要一个定义。
这里的章节/诗句:
9.4.2 / 4 -如果static
数据成员是const
积分或const
枚举类型,其在类定义声明可以指定一个其应是整数表达式(5.19)。 在这种情况下,构件可以出现在积分常量表达式。 该成员仍然在命名空间范围来限定,如果它是在程序中使用,并命名空间范围定义不应含有一个 。
见楚的答案可能的解决方法。
Bjarne的Stroustrup的例子在他的C ++ FAQ表明你是正确的,且仅当你把地址需要一个定义。
class AE {
// ...
public:
static const int c6 = 7;
static const int c7 = 31;
};
const int AE::c7; // definition
int f()
{
const int* p1 = &AE::c6; // error: c6 not an lvalue
const int* p2 = &AE::c7; // ok
// ...
}
他说 这表明它原本的工作。 也许你的分函数调用地址莫名其妙幕后。
另一种方式来做到这一点,对于整数类型反正就是定义常量在类枚举:
class test
{
public:
enum { N = 10 };
};
不只是诠释的。 但是你不能定义在类声明的价值。 如果你有:
class classname
{
public:
static int const N;
}
在.h文件,那么你必须有:
int const classname::N = 10;
在.cpp文件中。
这里是另一种方式来解决这个问题:
std::min(9, int(test::N));
(我觉得疯狂埃迪的回答正确地描述为什么存在问题。)
由于C ++ 11可以使用:
static constexpr int N = 10;
这在理论上仍然需要你定义在.cpp文件中恒定的,但只要你不把地址N
这是非常不可能的,任何编译执行会产生错误)。
C ++允许类内部定义的静态常量成员
不,3.1§2说:
的声明是一个定义,除非它宣称的功能,而无需指定函数体(8.4),它包含了extern声明符(7.1.1)或联动规范(7.5)和既不是初始化,也不是一个函数体, 它声明静态数据构件在类定义 (9.4),它是一个类名称声明(9.1),它是一种不透明的枚举声明(7.2),或者它是一个typedef声明(7.1.3)中,使用声明(7.3。 3),或使用指示符(7.3.4)。