C++ c++;自动多选

C++ c++;自动多选,c++,c++11,C++,C++11,在我的项目冒险中,我意识到如果我想根据条件初始化参数,我不能利用新的c++11 auto关键字的优势 基本上,我有一个这样的代码片段: auto foo = bar::getfoo(); 需要更改为: FOO foo if(cond){ foo = bar::getfoo(); } else { foo = baz::getotherfoo(); } 但是我需要用类型声明foo(因为编译器不知道我将使用相同的类型return。我想知道在这种情况下是否有使用auto关键字的方法。 我

在我的项目冒险中,我意识到如果我想根据条件初始化参数,我不能利用新的c++11 auto关键字的优势

基本上,我有一个这样的代码片段:

auto foo = bar::getfoo();
需要更改为:

FOO foo
if(cond){
   foo = bar::getfoo();
} else {
  foo = baz::getotherfoo();
}
但是我需要用类型声明foo(因为编译器不知道我将使用相同的类型return。我想知道在这种情况下是否有使用auto关键字的方法。 我提出的另一个解决方案是使用带有以下代码的?:运算符:

auto foo = cond ? bar::getfoo() : baz::getotherfoo();
但是,如果有两个以上的函数可供选择,我真的不想链接?:运算符。我想知道在这种情况下是否有好的模式可供使用。

这就是原因。它将为您提供表达式类型,而无需实际计算(并且您可以实现自动关闭):


您使用?:运算符的直觉是正确的-最好只初始化一次变量,避免冗余的默认构造/赋值周期

一种方法是将Foo创建的选择推迟到一个小的实用程序函数:

auto make_foo() -> decltype(bar::getfoo()) 
{
    if (condition1()) {
        return bar::getfoo();
    }
    else if(condition2()) {
        return baz::getfoo();
    }
    else {
        return banana::getfoo();
    }
}

void foo_test() {

    auto foo = make_foo();
}
注意,由于返回值优化,这是非常有效的

如果你有c++14,它就更好了——make_foo()函数可以推断出它自己的返回类型:

auto make_foo() {
    if (condition1()) {
        return bar::getfoo();
    }
    else if(condition2()) {
        return baz::getfoo();
    }
    else {
        return banana::getfoo();
    }
}
foo()
构造
a


使用C++14功能(大多数C++11编译器早期都支持此功能),但有条件地调用
foo
bar
并从中构造
a
。这种逻辑运算需要额外的移动,但编译器几乎肯定会省略它,这样它就不会真正发生。

很遗憾,您仅限于C++11。在C++14中,使用带有推断返回类型的函数或lambda。@mikey C++11编译器在lambdas上支持增强的返回类型推断。这个问题的措辞有点错误。没有多个选择。选择是一个,因为所有“路径”的计算结果都是相同的类型。但是OP想要某种“延迟”它位于变量声明语句之后。对于多选
boost::any
或类似的内容,都是必需的。@cerk你知道
if
子句进行赋值,而第一个简单子句(以及
子句)进行构造吗?@Yakk:可能是这样(我不熟悉每一个C++11编译器,所以不能评论),但问题的标签是“C++11”,而不是“几乎每一个C++11编译器”。这很好,但您需要定义make_foo的返回类型,因此它无法完成所有工作,因为您可以命名该类型。整个想法是分离返回类型bar::getfoo()和当前文件源(因此,当您更改它时,您不需要更改其他文件源代码,这不是c++14案例解决的问题,而是我无法使用的c++14)@cerkiewny好的,这可以通过一个小的编辑来完成,sec…doneEven一行:
return condition1()?bar::getfoo():condition2()?baz::getfoo():banana::getfoo()
由于赋值修改了常量类型的内容,这种方法不适用于常量类型。@Cerkewny这是一个不相关的问题,如果类型实际上是事先知道的,在这种情况下,可能需要使用三元数或lamda。您可以使用Yakks作为第一个示例,但替换if-else构造。@Lanting我认为cerkiewny所指的是decltype()可能解析为“const int&”(如果这是返回值),而auto将解析为“int”,定义可变副本(我认为这是本例中的正确行为)。您可以通过使用remove_const和remove_reference traits来解决此问题,但它很快就会变得麻烦。请澄清您的底部示例需要哪些c++14功能。我没有看到支持lambdas的编译器,也不支持它。@lefticus它需要对lambdas进行增强的返回类型推断。在c++11下,lambdas由一个stat组成ement可以是返回类型推断。在C++14下,我尝试过的每个C++11编译器都需要lambda返回类型推断(包括上面的内容),其中包括允许多个语句。C++14风格(据我回忆)一直都是预期的,但C++11“更简单”的风格被采用了(可能是为了让编译器实现者更容易)显然C++14风格已经足够简单了。
auto make_foo() {
    if (condition1()) {
        return bar::getfoo();
    }
    else if(condition2()) {
        return baz::getfoo();
    }
    else {
        return banana::getfoo();
    }
}
auto a = foo();
std::decay<decltype( foo() )>::type a;
if(cond){
  a = foo();
}else{
  a = bar();
}
auto a = [&]{
  if (cond)
    return foo();
  else
    return bar();
}();