有没有更短的写法 `StringPtr ? StringPtr:“空”`?

发布于 2024-11-30 01:36:41 字数 569 浏览 2 评论 0原文

我有这样的代码:

 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

有没有一种方法可以避免代码重复并且仍然拥有简洁的代码?

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 concise code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

探春 2024-12-07 01:36:41

你可以定义一个小函数:

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

You could define a small function:

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

Then your code becomes

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 wanted to be even more concise, you could do this (depending on what whatever_t is; if wstringstream already has an operator<< overload for that type, this won't work):

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

    return out;
}

Then your code becomes

std::wstringstream outstream;
outstream << prop.m_pwszOriginalVolumeName   << L";"
          << prop.m_pwszSnapshotDeviceObject << L";"
          << prop.m_pwszOriginatingMachine   << L";"
          << ... // some more strings here
零崎曲识 2024-12-07 01:36:41

函数或 lambda:

auto foo = [](const wchar * p) { return p ? p : L"null;" };

outstream << foo(prop.m_pwszOriginalVolumeName) << L";"
          << foo(prop.m_pwszSnapshotDeviceObject) << L";"
          << ...etc...

A function, or a lambda:

auto foo = [](const wchar * p) { return p ? p : L"null;" };

outstream << foo(prop.m_pwszOriginalVolumeName) << L";"
          << foo(prop.m_pwszSnapshotDeviceObject) << L";"
          << ...etc...
吐个泡泡 2024-12-07 01:36:41

其他的例子确实很好。还有另一种选择,但我不会推荐它(只是为了完整性而提及)。

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";"

但就像我说的,我不会推荐这个,我会使用像其他答案提到的辅助函数。

实际上,在某些情况下,它的执行方式与常规三元 if 不同,即 if 计算 a 具有副作用。从页面:

在这个简单的情况下,省略中间操作数的能力并不存在
特别有用。当第一个操作数变得有用时
确实或可能(如果它是宏参数)包含副作用。然后
在中间重复操作数会产生副作用
两次。省略中间操作数使用已经计算的值
不会因重新计算而产生不良影响。

请参阅http://gcc.gnu.org/onlinedocs/gcc/Conditionals.html

The other examples are really good. There is another option, though I wouldn't recommend it (only mentioning for completeness).

GCC has an extension called "Conditionals with Omitted Operands" Which basically looks like this:

x = a ?: b;

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

x = a ? a : b;

Just 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 like I said, I would not recommend this, I would use a helper function like the other answers mention.

There actually is a case where it performs differently than a regular ternary if, and that's if evaluating a has side effects. From the page:

In this simple case, the ability to omit the middle operand is not
especially useful. When it becomes useful is when the first operand
does, or may (if it is a macro argument), contain a side effect. Then
repeating the operand in the middle would perform the side effect
twice. Omitting the middle operand uses the value already computed
without the undesirable effects of recomputing it.

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

梦年海沫深 2024-12-07 01:36:41

一个简单的函数就可以解决问题。

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";" ;

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";" ;
好菇凉咱不稀罕他 2024-12-07 01:36:41

您可以使用辅助函数:

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

You could use a 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文