Simon says; I've stopped using ?: because it isn't as readable as an if .. then .. else. ...
I, personally, don't find the readability of the conditional operator (?:) a problem. No more than I find readability of assignments or pointer operations a problem. I can see how that since the conditional operator is only appropriate for use in certain circumstances, some programmers may not have come across it very often and for them it may be harder to understand than a construct that they know well.
In C++ I find that I use the conditional operator most often when the result is const as obviously I can't use the alternative if then else structure and still make the result const without resorting to a helper function to do the work....
So something like this;
const DWORD dwServiceType = ownProcess ? SERVICE_WIN32_OWN_PROCESS : SERVICE_WIN32_SHARE_PROCESS;
DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS;
if (!ownProcess)
{
dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
}
size_t BytesPerLine(
const size_t lineLength)
{
size_t bytesPerLine = 0;
// useful comments about why?
if (lineLength != 0)
{
bytesPerLine = (lineLength - 1)/3;
}
return bytesPerLine;
}
...
const size_t bytesPerLine = BytesPerLine(lineLength);
const size_t bytesPerLine = lineLength != 0 ? (lineLength - 1) / 3 : 0;
As I've said before, I'm keen on const so, for me, it's important not to make a variable non const just because you need a complex assignment for it.
Another place that the conditional operator is useful is in constructor initialisation lists; you simply can't replace it with an if then else so you're left with either the conditional operator or a helper function.
CAsyncSocketConnectionManager::CAsyncSocketConnectionManager(
bool sslActive,
CContext &sslContext,
bool verifyPeer,
IIOPool &pool,
IAllocateAsyncSockets &socketAllocator,
IAllocateBuffers &bufferAllocator)
: JetByteTools::Socket::CAsyncSocketConnectionManager(pool, socketAllocator, bufferAllocator, false),
m_pContext(sslActive ? &sslContext : 0), // <-----
m_verifyPeer(verifyPeer),
m_SSLConnectorIndex(socketAllocator.RequestUserDataSlot(_T("JeByteTools::OpenSSL::CAsyncSocketConnectionManager"))),
m_bufferAllocator(bufferAllocator)
{
}
PostIoOperation(pSocket, pBuffer, m_postZeroByteReads ? IO_Zero_Byte_Read_Request : IO_Read_Request);
LogMessage(_T("UserData") + (showUserData ? _T(": ") + ToString((int*)pUserData) : _T("")));
Like everything in programming, it depends. It's a useful construct, it can be misused but it can also be used to enhance the code that it's used in. I usually prefer not to nest conditional operators, but I have done it from time to time...
As for the main purpose of Simon's post, the C# ?? operator, it looks like syntactic sugar to me, but I'd be interested to see the 'nullable type' examples done with the conditional operator for comparison.