在变量初始化期间使用C ++ lambda函数
我想很多人都有这种代码:
int foo;
switch (bar) {
case SOMETHING: foo = 5; break;
case STHNELSE: foo = 10; break;
...
}
但是这个代码有一些缺点:
foo
变量不是常量,而应该是 所以我开始想知道是否有一种方法来“改善”这种代码,并且我有这样一个想法:
const int foo = [&]() -> int {
switch (bar) {
case SOMETHING: return 5;
case STHNELSE: return 10;
...
}
}();
注意:第一对括号不是强制性的,但MSVC ++不支持这一点
如果三元运算符太复杂,需要通过指针进行初始化的变量(如DirectX函数),则可以使用与if-else相同的技巧。
我的问题是:
编辑:这就是我所说的“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(); });
}();
这在其他语言中是相当常见的技巧。 几乎Scheme的每个高级功能都是根据立即调用的lambda表达式来定义的。
在JavaScript中,它是“模块模式”的基础,例如
var myModule = (function() {
// declare variables and functions (which will be "private")
return {
// populate this object literal with "public" functions
};
})();
所以一个匿名函数被声明并立即被调用,这样任何内部细节都被隐藏起来,只有返回值被暴露在外部。
唯一的缺点是,在随便阅读代码时, return
语句似乎是从外部函数返回的(在Java lambda战争期间对此有激烈的争论)。 但这只是一旦你的语言有lambda表达式,你必须习惯。
象C ++这样的命令式语言中有许多语言特性,它们能从返回值(而不是像void
函数)中受益。 例如, if
有替代方案,第三级操作员expr ? a : b
expr ? a : b
。
在Ruby中,几乎所有的语句都可以被评估,所以不需要单独的语法来提供返回值。 如果C ++以这种方式工作,这将意味着:
auto result = try
{
getIntegerSomehow();
}
catch (const SomeException &)
{
0;
}
在这种情况下,我根本没有看到任何使用开关盒的理由。 任何像样的编译器都会像switch开关一样用if语句生成一样快的代码。
if(bar == SOMETHING)
foo = 5;
else if(bar == STHNELSE)
foo = 10;
链接地址: http://www.djcxy.com/p/2449.html
上一篇: Using C++ lambda functions during variable initialisation