我有这段代码:
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
有没有办法避免代码重复,仍然有简洁的代码?
答案 0 :(得分:6)
您可以定义一个小函数:
whatever_t strOrNull(whatever_t str) {
return str ? str : L"null";
}
然后您的代码变为
std::wstringstream outstream;
outstream << strOrNull(prop.m_pwszOriginalVolumeName) << L";"
<< strOrNull(prop.m_pwszSnapshotDeviceObject) << L";"
<< strOrNull(prop.m_pwszOriginatingMachine) << L";"
<< ... // some more strings here
或者,如果您想要更简洁,可以执行此操作(取决于whatever_t
是什么;如果wstringstream
已经为该类型设置了operator<<
,则会赢得此优惠工作):
wstringstream& operator<<(wstringstream& out, whatever_t str) {
if (str)
out << str;
else
out << L"null";
return out;
}
然后您的代码变为
std::wstringstream outstream;
outstream << prop.m_pwszOriginalVolumeName << L";"
<< prop.m_pwszSnapshotDeviceObject << L";"
<< prop.m_pwszOriginatingMachine << L";"
<< ... // some more strings here
答案 1 :(得分:2)
一个函数,或一个lambda:
auto foo = [](const wchar * p) { return p ? p : L"null;" };
outstream << foo(prop.m_pwszOriginalVolumeName) << L";"
<< foo(prop.m_pwszSnapshotDeviceObject) << L";"
<< ...etc...
答案 2 :(得分:2)
一个简单的功能应该可以解决问题。
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";" ;
答案 3 :(得分:2)
您可以使用辅助功能:
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
答案 4 :(得分:2)
其他例子非常好。还有另一种选择,虽然我不推荐它(仅提及完整性)。
GCC有一个名为“带有省略操作数的条件”的扩展名,其基本上如下所示:
x = a ?: b;
与(与您的情况类似,请参见下文了解更多信息)相同:
x = a ? a : b;
不太便携。所以你可以写:
std::wstringstream outstream;
outstream << (prop.m_pwszOriginalVolumeName ?: L"null") << L";"
<< (prop.m_pwszSnapshotDeviceObject ?: L"null") << L";"
<< (prop.m_pwszOriginatingMachine ?: L"null") << L";"
但就像我说的那样,不会推荐这个,我会像其他答案一样使用帮助函数。
实际上有一种情况,它的表现与常规的三元不同,如果评估a
有副作用。从页面:
在这个简单的例子中,省略中间操作数的能力不是 特别有用。当它变得有用时是第一个操作数 是,或可能(如果它是一个宏参数),包含副作用。然后 在中间重复操作数将执行副作用 两次。省略中间操作数使用已计算的值 没有重新计算它的不良后果。