Here's the deal. I have a static class which contains several static functions used for getting input. The class contains a private static member variable for indicating whether the user entered any information. Each input method checks to see whether the user entered any information, and sets the status variable accordingly. I think this would be a good time to use the ternary operator. Unfortunately, I can't, because the compiler doesn't like that.
I replicated the problem, then simplified my code as much as was possible to make it easy to understand. This is not my original code.
Here's my header file:
#include <iostream>
using namespace std;
class Test {
public:
void go ();
private:
static const int GOOD = 0;
static const int BAD = 1;
};
Here's my implementation with the ternary operator:
#include "test.h"
void Test::go () {
int num = 3;
int localStatus;
localStatus = (num > 2) ? GOOD : BAD;
}
Here's main function:
#include <iostream>
#include "test.h"
using namespace std;
int main () {
Test test = Test();
test.go();
return 0;
}
When I try to compile this, I get this error message:
test.o: In function `Test::go()':
test.cpp:(.text+0x17): undefined reference to `Test::GOOD'
test.cpp:(.text+0x1f): undefined reference to `Test::BAD'
collect2: ld returned 1 exit status
However, if I replace this:
localStatus = (num > 2) ? GOOD : BAD;
with this:
if (num > 2) {
localStatus = GOOD;
} else {
localStatus = BAD;
}
The code compiles and runs as expected. What obscure C++ rule or GCC corner case is responsible for this lunacy? (I'm using GCC 4.4.1 on Ubuntu 9.10.)
Moreover, as has been pointed out, at the byte code level there's really no difference between the ternary operator and if-then-else. As in the above example, the decision on which to choose is based wholly on readability.
It is not faster. There is one difference when you can initialize a constant variable depending on some expression: const int x = (a<b) ?
Advantages of Ternary Operator It will improve the readability of the code. The code becomes more straightforward. Makes basic if/else logic easier to code. Instead of breaking your output building for if/else statements,you can do your if/else logic in line with output.
The ternary operator take three arguments: The first is a comparison argument. The second is the result upon a true comparison. The third is the result upon a false comparison.
This is according to the C++ Standard. The ternary operator does constitute a single lvalue that will refer to either GOOD
or BAD
at runtime. The lvalue to rvalue conversion is not applied immediately to either the lvalue GOOD
or BAD
, and therefor you require a definition of GOOD
and BAD
.
See the core language issue report http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#712 .
As a workaround, you can apply explicit casts to int
(which reads their values, thereby doing an lvalue to rvalue conversion) or use an operator that reads the value, like +
:
localStatus = (num > 2) ? +GOOD : +BAD;
class Test {
static const int GOOD = 0;
static const int BAD = 1;
};
These are only declarations; they are not definitions. You need to provide definitions of the static member variables, outside of the definition of the class, in one of your .cpp files:
const int Test::GOOD;
const int Test::BAD;
Alternatively, for integer constants, it is often more convenient to use an enum
:
class Test {
enum {
GOOD = 0,
BAD = 1
};
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With