在我的项目冒险中,我意识到如果我想根据条件初始化参数,我就无法利用新的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();
但如果有两个以上的功能可供选择,我真的不想连锁吗? :运营商。我想知道在这种情况下是否有任何好的模式。
答案 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编译器),但有条件地调用foo
或bar
并从中构造a
。这种逻辑运算需要额外的动作,但编译器几乎肯定会忽略它,所以它实际上不会发生。