Dav*_*ams 19 c++ gcc compiler-errors
这是一个非常基本的问题,但我不明白为什么下面的代码不能在GCC 4.6.1上编译.它在VS 2008 SP1上编译:
#include <iostream>
class MyClass
{
public:
const static int MinValue = -1000;
const static int MaxValue = 1000;
};
void printValue(int i)
{
std::cout << i << std::endl;
}
int main(int argc, char** argv)
{
printValue(MyClass::MinValue);
printValue(MyClass::MaxValue);
printValue(argc < 42 ? MyClass::MinValue : MyClass::MaxValue); //This line gives the error
}
Run Code Online (Sandbox Code Playgroud)
GCC说:
david@David-Laptop:~/temp$ g++ test.cpp
/tmp/ccN2b95G.o: In function `main':
test.cpp:(.text+0x54): undefined reference to `MyClass::MinValue'
test.cpp:(.text+0x5c): undefined reference to `MyClass::MaxValue'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
但是,如果我取出第三次调用'printValue',那么它会构建并正常运行.所以它与'?'有关 operator ...这样使用它是无效的吗?此外,如果我用'true'或'false'替换'argc <42',它也可以很好地构建.
有任何想法吗?!
Mik*_*our 18
根据"一个定义规则",如果使用了odr,变量必须只有一个定义.这由C++ 11标准定义:
3.2/2一个变量或非重载函数,其名称显示为一个可能被评估的表达式是odr-used,除非它是一个满足出现在常量表达式中的要求的对象,并且立即应用了左值到右值的转换.
和ODR本身:
3.2/3每个程序应包含该程序中每个非内联函数或变量的一个定义; 无需诊断.
作为函数调用参数,它们不是使用odr:它们是在其声明中指定值的常量,因此可以出现在常量表达式中; 它们按值传递,因此立即转换为rvalues.
在条件表达式中使用它们时不是这种情况.由于两个都是引用相同类型的左值,根据定义条件运算符的相当复杂的规则之一,条件表达式的结果将是左值:
5.16/4如果第二个和第三个操作数是相同值类别的glvalues并且具有相同的类型,则结果是该类型和值类别.
(此规则允许表达式(a?b:c)=d.)
因此,常量本身不会立即转换为rvalues,并且由于运行时条件,条件表达式不能出现在常量表达式中; 因此,它们使用起来很多,所以需要一个定义.
如您所知,将条件更改为常量表达式可修复链接错误; 所以会改变一个常量的类型.但是现在的表达要求他们在一个(并且只有一个)翻译单元中有一个定义:
const int MyClass::MinValue;
const int MyClass::MaxValue;
Run Code Online (Sandbox Code Playgroud)
您需要在类声明之外定义静态成员:
class MyClass
{
public:
const static int MinValue;
const static int MaxValue;
};
//implementation file
const int MyClass::MinValue = -1000;
const int MyClass::MaxValue = 1000;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
479 次 |
| 最近记录: |