在变量初始化期间使用C++ lambda函数

Tom*_*a17 7 c++ lambda c++11

我想很多人都有这样的代码:

int foo;
switch (bar) {
  case SOMETHING: foo = 5;  break;
  case STHNELSE:  foo = 10; break;
  ...
}
Run Code Online (Sandbox Code Playgroud)

但是这段代码有一些缺点:

  • 你很容易忘记"休息"
  • foo变量不是const的,而应该是
  • 它不漂亮

所以我开始想知道是否有办法"改进"这种代码,我得到了这个小小的想法:

const int foo = [&]() -> int {
  switch (bar) {
    case SOMETHING: return 5;
    case STHNELSE:  return 10;
    ...
  }
}();
Run Code Online (Sandbox Code Playgroud)

注意:第一对括号不是强制性的,但MSVC++尚不支持

您可以使用if-else使用相同的技巧,其中三元运算符太复杂,需要通过指针传递的变量进行初始化(如DirectX函数)等.

我的问题是:

  • 我没看到这个代码有什么问题吗?
  • 你觉得它比上面的更好吗?
  • g ++似乎内联函数,但你认为所有编译器都会这样做吗?

编辑:这就是我所说的"DirectX功能"

_xAudio2 = [&]() -> std::shared_ptr<IXAudio2> {
    IXAudio2* ptr = nullptr;
    if (FAILED(XAudio2Create(&ptr, xAudioFlags, XAUDIO2_DEFAULT_PROCESSOR)))
        throw std::runtime_error("XAudio2Create failed");
    return std::shared_ptr<IXAudio2>(ptr, [](IUnknown* ptr) { ptr->Release(); });
}();
Run Code Online (Sandbox Code Playgroud)

Dan*_*ker 3

这是其他语言中相当常见的技术。几乎Scheme 的每个高级功能都是根据立即调用的lambda 来定义的。

在 JavaScript 中,它是“模块模式”的基础,例如

var myModule = (function() {

    // declare variables and functions (which will be "private")

    return {
       // populate this object literal with "public" functions
    };

})();
Run Code Online (Sandbox Code Playgroud)

因此,声明并立即调用匿名函数,从而隐藏任何内部细节,仅将返回值暴露在外部。

唯一的缺点是,在随意阅读代码时,这些return语句看起来像是从外部函数返回的(在 Java lambda 战争期间对此存在激烈的争议)。但是,一旦您的语言有了 lambda,您就必须习惯这一点。

像 C++ 这样的命令式语言有许多语言特性,它们会受益于能够返回一个值(而不是像一个void函数)。例如,if有一个替代方案,三级运算符expr ? a : b

在 Ruby 中,几乎所有语句都可以被计算,因此不需要可以提供返回值的单独语法。如果 C++ 以这种方式工作,这将意味着:

auto result = try
{
    getIntegerSomehow();
}
catch (const SomeException &)
{
    0;
}
Run Code Online (Sandbox Code Playgroud)