Is there a shorter way to write `StringPtr? StringPtr: "null" `?

I have this code:

std::wstringstream outstream; outstream << (prop.m_pwszOriginalVolumeName ? prop.m_pwszOriginalVolumeName : L"null") << L";" << (prop.m_pwszSnapshotDeviceObject ? prop.m_pwszSnapshotDeviceObject : L"null") << L";" << (prop.m_pwszOriginatingMachine ? prop.m_pwszOriginatingMachine : L"null") << L";" << ... // some more strings here 

Is there a way to avoid code duplication and still have compressed code?

+4
source share
5 answers

You can define a little function:

 whatever_t strOrNull(whatever_t str) { return str ? str : L"null"; } 

Then your code will become

 std::wstringstream outstream; outstream << strOrNull(prop.m_pwszOriginalVolumeName) << L";" << strOrNull(prop.m_pwszSnapshotDeviceObject) << L";" << strOrNull(prop.m_pwszOriginatingMachine) << L";" << ... // some more strings here 

Or, if you want to be more concise, you can do this (depending on what whatever_t , if wstringstream already has operator<< overload for this type, this will not work):

 wstringstream& operator<<(wstringstream& out, whatever_t str) { if (str) out << str; else out << L"null"; return out; } 

Then your code will become

 std::wstringstream outstream; outstream << prop.m_pwszOriginalVolumeName << L";" << prop.m_pwszSnapshotDeviceObject << L";" << prop.m_pwszOriginatingMachine << L";" << ... // some more strings here 
+6
source

Function or Lambda:

 auto foo = [](const wchar * p) { return p ? p : L"null;" }; outstream << foo(prop.m_pwszOriginalVolumeName) << L";" << foo(prop.m_pwszSnapshotDeviceObject) << L";" << ...etc... 
+2
source

A simple function should do the trick.

 wchar_t* filterNullString(wchar_t* str) { static wchar const* nullStr = L"null"; return str ? str : nullStr; } std::wstringstream outstream; outstream << filterNullString(prop.m_pwszOriginalVolumeName) << L";" << filterNullString(prop.m_pwszSnapshotDeviceObject)<< L";" << filterNullString(prop.m_pwszOriginatingMachine)<< L";" ; 
+2
source

You can use the helper function:

 const wchar_t *SafeOutput(const wchar_t *str) { return str ? str : L"null"; } // Analogous function for ANSI strings ... outstream << SafeOutput(prop.m_pwszOriginalVolumeName) << L";" << SafeOutput(prop.m_pwszSnapshotDeviceObject) << L";" << SafeOutput(prop.m_pwszOriginatingMachine) << L";" << ... // more strings here 
+2
source

Other examples are really good. There is another option, although I would not recommend it (for completeness only).

GCC has an extension called โ€œLegends with Omitted Operands,โ€ which basically looks like this:

 x = a ?: b; 

which is the same (in simple cases like yours, see below for more information):

 x = a ? a : b; 

Only less portable. So you could write:

 std::wstringstream outstream; outstream << (prop.m_pwszOriginalVolumeName ?: L"null") << L";" << (prop.m_pwszSnapshotDeviceObject ?: L"null") << L";" << (prop.m_pwszOriginatingMachine ?: L"null") << L";" 

But, as I said, I would not want to recommend this, I would use a helper function, as the other answers mention.

In fact, this is the case when it is performed differently than the usual triple if and if there are side effects when evaluating a . On the page:

In this simple case, the ability to omit the middle operand is not particularly useful. When it becomes useful, it is when the first operand or can (if it is a macro argument) contains a side effect. then repeating the operand in the middle will perform a side effect twice. Lowering the middle operand uses the already calculated value without the undesirable consequences of reprogramming.

See http://gcc.gnu.org/onlinedocs/gcc/Conditionals.html

+2
source

All Articles