【问题标题】:Is there a shorter way of writing `StringPtr ? StringPtr : "null"`?有没有更短的写 `StringPtr 的方法?字符串指针:“空”`?
【发布时间】:2011-08-16 19:25:49
【问题描述】:

我有这个代码:

 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

有没有办法避免代码重复,仍然有简洁的代码?

【问题讨论】:

  • 只需创建一个函数或接受 StringPtr,然后运行您的三元条件运算符:outstream
  • @Mooing Duck,我正要建议一个宏作为一个选项:D
  • @Duck:宏不尊重命名空间,如果不对参数进行两次评估,就很难实现这一点。一个函数会好很多。

标签: c++ conditional-operator


【解决方案1】:

你可以定义一个小函数:

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&lt;&lt; 重载,这将不起作用):

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

【讨论】:

  • 恭喜您成为众多几乎相同答案中的第一个。
  • @Mark 看看是否更好。
  • 没有必要道歉或更新您的答案 - 我的祝贺是真诚的。这是一个显而易见的答案,但第一个越过终点线的人应该得到奖励。
  • whatever_t 很可能是wchar_t*,在这种情况下,operator&lt;&lt; 已经过载。
【解决方案2】:

一个函数,或者一个 lambda:

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

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

【讨论】:

    【解决方案3】:

    其他例子都很好。还有另一种选择,尽管我不推荐它(仅出于完整性考虑)。

    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 不同,那就是如果评估 a 有副作用。从页面:

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

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

    【讨论】:

    • 不完全一样:它只计算一次a
    【解决方案4】:

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

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

    【讨论】:

    • static 修饰符是否在这里改变了什么?我认为文字无论如何都存储在不可修改的字符串池中......好吧,这取决于实现,但对于所有打开优化的主要编译器都应该是这种情况,对吧?
    • @Felix static 使得每次调用函数时都不必创建变量。虽然字符串可能仍然存储在不可修改的字符串池中,但static 消除了一些不必要的工作。
    • 它可能是 C++ 标准的一部分,但我不确定,所以我确定我做对了。
    【解决方案5】:

    你可以使用辅助函数:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-10
      • 1970-01-01
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      相关资源
      最近更新 更多