我已经养成了使用直接列表初始化编写代码的习惯,如下所示,它更加有效,并且非常有用,可以防止隐式缩小narrowing:
int i {0};
string s {""};
char c {'a'};
bool b {false};
auto num {100}; // But this??
但是当涉及到自动推断类型时,我听说这种写法被认为是不好的或者不被推荐的,为什么呢?
我已经养成了使用直接列表初始化编写代码的习惯,如下所示,它更加有效,并且非常有用,可以防止隐式缩小narrowing:
int i {0};
string s {""};
char c {'a'};
bool b {false};
auto num {100}; // But this??
但是当涉及到自动推断类型时,我听说这种写法被认为是不好的或者不被推荐的,为什么呢?
这是一个示例,说明使用该语法会失败:
struct Foo{};
void eatFoo (const Foo& f){}
int main() {
Foo a;
auto b{a};
eatFoo(b);
}
你可能希望这样做没问题: b
应该是一个 Foo
类型并传递给 eatFoo
函数。不幸的是,这会导致编译错误:
prog.cpp:11:10: error: invalid initialization of reference of type 'const Foo&' from expression of type 'std::initializer_list<Foo>'
eatFoo(b);
正如您所看到的,b
实际上是类型为 std::initializer_list<Foo>
。在这种情况下显然不是我们想要的。如果我们将它改为 auto b = a
,那么这样就可以正常工作了。然后,如果我们仍然想使用 auto
,但明确声明类型,我们可以将其改为 auto b = Foo{a}
并让编译器省略副本。
auto
,但显式声明类型,那真的没有意义。auto
的整个作用就是避免声明类型。我知道在C#中有一些人会写var x =(string)null;
而不是string x = null;
,但他们只占极少数,我从未见过任何人真正为编写此类代码进行辩护。我无法想象在C++中有任何有效的论据支持这样做。 - user743382struct S { explicit S(int); };
,S s = 3;
无法编译。而 auto s = S{3};
则被接受。系统地使用 auto v = T{i};
语法意味着编译器会少一些机会警告您可能犯的错误。 - user743382auto x = std::make_unique<SomeTypeName>(bla...);
比重复类型更好。 - M.M
int n; int & r { n };
曾经是有问题的。而auto x = { 1, 2 }
转化为auto y = { 1 }
可能会让人感到意外。基本上,花括号引入了很多不一致性,有些人认为这不值得让读者感到困惑。 - Kerrek SBinitializer_list
的类型系统处理是一个糟糕的笑话。它的工作方式符合您的期望,除非它不符合。 - Tim Seguine