Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么不';静态成员变量与三元运算符配合得好吗?_C++_Static_Ternary Operator_Static Members - Fatal编程技术网

C++ 为什么不';静态成员变量与三元运算符配合得好吗?

C++ 为什么不';静态成员变量与三元运算符配合得好吗?,c++,static,ternary-operator,static-members,C++,Static,Ternary Operator,Static Members,事情是这样的。我有一个静态类,它包含几个用于获取输入的静态函数。该类包含一个私有静态成员变量,用于指示用户是否输入了任何信息。每个输入法检查用户是否输入了任何信息,并相应地设置状态变量。我认为现在是使用三元运算符的好时机。不幸的是,我不能,因为编译器不喜欢这样 我复制了这个问题,然后尽可能简化代码,使其易于理解。这不是我的原始代码 这是我的头文件: #include <iostream> using namespace std; class Test { public:

事情是这样的。我有一个静态类,它包含几个用于获取输入的静态函数。该类包含一个私有静态成员变量,用于指示用户是否输入了任何信息。每个输入法检查用户是否输入了任何信息,并相应地设置状态变量。我认为现在是使用三元运算符的好时机。不幸的是,我不能,因为编译器不喜欢这样

我复制了这个问题,然后尽可能简化代码,使其易于理解。这不是我的原始代码

这是我的头文件:

#include <iostream>

using namespace std;

class Test {
public:
    void go ();
private:
    static const int GOOD = 0;
    static const int BAD = 1;
};
以下是主要功能:

#include <iostream>
#include "test.h"

using namespace std;

int main () {
    Test test = Test();
    test.go();
    return 0;
}
但是,如果我将其替换为:

localStatus = (num > 2) ? GOOD : BAD;
为此:

if (num > 2) {
    localStatus = GOOD;
} else {
    localStatus = BAD;
}
代码按预期编译和运行。什么模糊的C++规则或GCC角落的情况是造成这种疯癫的原因?(我在Ubuntu 9.10上使用GCC4.4.1。)

这些只是声明;它们不是定义。您需要在类定义之外的一个.cpp文件中提供静态成员变量的定义:

const int Test::GOOD;
const int Test::BAD;
或者,对于整数常量,使用
枚举通常更方便:

class Test {
    enum { 
        GOOD = 0,
        BAD = 1 
    };
};

我觉得你的代码很好。并且
ideone
同意:请参阅。但gcc-4.3.4就是这样。但是,我的gcc-4.4.0不接受它。所以不管是什么原因,都不明显

编辑以添加:以下变体在gcc-4.4.0下编译:

int localStatus = 42 ? GOOD : BAD;
提醒:以下代码未编译:

int localStatus = (num == 42) ? GOOD : BAD;

有人在某个地方搞砸了。

< P>这是按照C++标准。三元运算符确实构成了一个单独的左值,在运行时将引用
GOOD
BAD
。左值到右值的转换不会立即应用于左值
GOOD
BAD
,因此您需要定义
GOOD
BAD

见核心语言问题报告

作为一种解决方法,您可以将显式强制转换应用于
int
(读取其值,从而进行左值到右值的转换)或使用读取值的运算符,如
+

localStatus = (num > 2) ? +GOOD : +BAD;

为什么缺少定义会困扰三元运算符而不是标准赋值运算符?它不是那么简单。看到我的答案了。@Evan:你说的是哪个赋值运算符?给好的和坏的赋值的那个?@Evan:我不是100%确定,但是我会尝试回答这个问题:当你使用直接赋值时,
GOOD
BAD
只直接用作右值。但是,当您使用条件运算符时,条件表达式
num>2?好:BAD
本身就是一个左值表达式,因此左值到右值的转换在选择
GOOD
BAD
之后才正式发生,因此需要实际对象(带定义)。标准在哪里区分这两种情况?它们不是都“使用”
GOOD
,因此需要定义吗?我认为gcc足够聪明,可以避免在左值
良好
用作赋值RHS的情况下使用外部链接(因此立即进行左值右值转换),但在三元运算符中使用左值
良好
的情况下没有管理外部链接,但是我准备相信我错了。@Steve如果你做了
+GOOD
int a=GOOD
,你就在左值
GOOD
上进行左值到右值的转换(“直接”-见3.2p2,在这种情况下你不“使用”变量)。如果你做
inta=x?a:b
,你将对三元运算符产生的左值进行左值到右值的转换,而不是对
a
b
产生的左值进行转换。啊,你对James的评论回答了我的问题。它们的区别在于在C++03之后但在2008年缺陷出现之前插入到草稿中的文本。我认为目前的标准符合我所说的。我的打印副本和我2003年的PDF(E)都说,“如果对象或非重载函数的名称出现在可能计算的表达式中,则使用该对象或非重载函数。”没有例外。我不确定是否有人在某个地方搞砸了。我相信,在第一种情况下,唯一发生的事情是,表达式被优化了。但真正的问题仍然存在。
int localStatus = 42 ? GOOD : BAD;
int localStatus = (num == 42) ? GOOD : BAD;
localStatus = (num > 2) ? +GOOD : +BAD;