c ++ auto有多种选择

时间:2015-05-20 10:36:46

标签: c++ c++11

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

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

auto foo = bar::getfoo();

需要更改为:

FOO foo
if(cond){
   foo = bar::getfoo();
} else {
  foo = baz::getotherfoo();
}

但是我需要用类型声明foo(因为编译器不能知道我将使用相同类型的返回。我想知道在这种情况下是否有任何使用auto关键字的方法。 我想出的另一个解决方案是使用? :运算符有这样的代码:

auto foo = cond ? bar::getfoo() : baz::getotherfoo();

但如果有两个以上的功能可供选择,我真的不想连锁吗? :运营商。我想知道在这种情况下是否有任何好的模式。

3 个答案:

答案 0 :(得分:7)

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

这样做的一种方法是将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();
    }
}

答案 1 :(得分:5)

这是decltype的用途。它将为您提供表达式的类型,而无需实际评估(并且您可以在关闭时实现auto):

decltype(bar::getfoo()) foo;
if (....) {foo = ...;} else {foo = ...;}

答案 2 :(得分:4)

auto a = foo();

a构建foo();

std::decay<decltype( foo() )>::type a;
if(cond){
  a = foo();
}else{
  a = bar();
}

默认构造a然后根据foo()为其指定bar()cond的结果。

decay是必需的,否则foo()会返回引用,或者decltype会推断出错误的&#39}。输入a

auto a = [&]{
  if (cond)
    return foo();
  else
    return bar();
}();

使用C ++ 14功能(早期支持大多数C ++ 11编译器),但有条件地调用foobar并从中构造a。这种逻辑运算需要额外的动作,但编译器几乎肯定会忽略它,所以它实际上不会发生。