auto和static_casts - 良好的做​​法

Daw*_*dPi 7 c++ coding-style c++11

在Scott Meyer的书"Effective Modern C++"中,我们可以读到:

std::vector<bool> features(const Widget& w);
Widget w;
…
bool highPriority = features(w)[5];
…
processWidget(w, highPriority); 
Run Code Online (Sandbox Code Playgroud)

以及auto的选项

auto highPriority = features(w)[5];
Run Code Online (Sandbox Code Playgroud)

这会导致未定义的行为,因为features()返回的事实是std::vector<bool>,std::vector<bool>::reference在返回值时使用类型的代理对象opearator[].

作为解决方案,建议不要停止使用auto,而是使用static_casts.

所以Scott Meyers建议使用:

auto highPriority = static_cast<bool>(features(w)[5]);
Run Code Online (Sandbox Code Playgroud)

代替:

bool highPriority = features(w)[5];
Run Code Online (Sandbox Code Playgroud)

我的问题是:这两者之间有什么真正的区别?在我看来两者都是相同的,因为这两种方法都以完全相同的方式使重构变得更难(在函数功能中改变返回值类型不会使变量highPriority成为不同类型)而第二种方法更短.

Bo *_*son 7

如果您不喜欢界面features,可以在辅助函数中隐藏丑陋

bool is_high_priority(const Widget& w)
{ return features(w)[5]; }
Run Code Online (Sandbox Code Playgroud)

现在你的

auto highPriority = is_high_priority(w);
Run Code Online (Sandbox Code Playgroud)

按预期工作.


Che*_*Alf 5

使用features返回a的函数std::vector<bool>,

auto highPriority = features(w)[5];
Run Code Online (Sandbox Code Playgroud)

存储逻辑参考.存储的对象是指不再存在的向量.使用它然后会产生未定义的行为.

相反

bool const highPriority = features(w)[5];
Run Code Online (Sandbox Code Playgroud)

要么

auto const highPriority = !!features(w)[5];
Run Code Online (Sandbox Code Playgroud)

或者,正如斯科特所建议的那样 - 但是我的口味太过冗长 - 请使用static_cast.

存储的对象现在是bool.

这三种表达同一声明的方式之间没有功能差异.唯一的区别是非功能性的:在我看来,不必要的冗长static_cast,以及可能!!会从一个常见的编译器中抑制对性能的愚蠢警告.