虽然下面的例子编译得很好,除了最后一行有错误,我想知道范围内这个'范围'的来龙去脉?也是这个术语,如果有的话。
考虑这些括号:
void func()
{
int i = 0;
{ // nice comment to describe this scope
while( i < 10 )
++i;
}
{ // nice comment to describe this scope
int j= 0;
while( j< 10 )
++j;
}
i = 0; // OK
// j = 0; // error C2065
}
考虑一下:
error C2065: 'j' : undeclared identifier
修改 Accepted answer来自bitmask,但我认为每个人都应将其置于anio answer的背景下。特别是,引用:“也许你应该将你的功能分解为两个功能”
答案 0 :(得分:7)
<强>不要即可。无论如何!
将数据尽可能保持在本地并尽可能保持const有两个主要优点:
此外,这对于文档总结函数的特定部分所做的工作非常有用。
我听说这被称为显式或虚拟范围。
答案 1 :(得分:6)
我个人认为在函数中添加额外的作用域并没有多大价值。如果您依靠它来分离函数的各个部分,也许您应该将函数分解为2个函数。较小的功能比较大的功能更好。你应该努力使用易于理解的小功能。
函数中范围的合法使用是限制锁定的持续时间:
int doX()
{
// Do some work
{
//Acquire lock
} // Lock automatically released because of RAII
}
内部范围有效地限制了锁定的代码。我相信这是常见的做法。
答案 2 :(得分:4)
是的,肯定 - 这是一个很好的习惯,让你的变量尽可能地保持在本地!一些例子:
for (std::string line; std::getline(std::cin, line); ) // does not
{ // leak "line"
// process "line" // into ambient
} // scope
int result;
{ // putting this in a separate scope
int a = foo(); // allows us to copy/paste the entire
a += 3; // block without worrying about
int b = bar(a); // repeated declarators
result *= (a + 2*b);
}
{ // ...and we never really needed
int a = foo(); // a and b outside of this anyway!
a += 3;
int b = bar(a);
result *= (a + 2*b);
}
有时需要范围进行同步,并且您希望保持关键部分尽可能短:
int global_counter = 0;
std::mutex gctr_mx;
void I_run_many_times_concurrently()
{
int a = expensive_computation();
{
std::lock_guard<std::mutex> _(gctr_mx);
global_counter += a;
}
expensive_cleanup();
}
答案 3 :(得分:3)
显式范围通常不会用于评论目的,但如果您觉得它使您的代码更具可读性,我认为这样做没有任何损害。
典型用法是avoiding name clashes and controlling when the destructors are called。
答案 4 :(得分:2)
一对花括号定义范围。在范围内声明或定义的名称在该范围之外是不可见的,这就是为什么最后没有定义j
的原因。如果范围中的名称与之前定义的名称相同且在该范围之外,则它会隐藏外部名称。