【问题标题】:Defining variables in control structures在控制结构中定义变量
【发布时间】:2011-11-24 08:42:15
【问题描述】:

根据标准,在控制结构中声明变量与在其他地方声明变量之间的行为有什么区别?我似乎找不到任何提及它。

如果我的意思不清楚,这里有一个例子:

if (std::shared_ptr<Object> obj = objWeakPtr.lock())

如您所见,我在 if 块中声明并初始化了一个局部变量 obj

另外,是否有任何技术原因说明为什么在使用此语法代替条件时没有给出任何特殊行为?例如,添加一组额外的括号会导致编译器错误;这也可以防止变量与其他条件链接。

// Extra brackets, won't compile.
if ((std::shared_ptr<Object> obj = objWeakPtr.lock()))

// If the above were valid, something like this could be desirable.
if ((std::shared_ptr<Object> obj = objWeakPtr.lock()) && obj->someCondition())

【问题讨论】:

  • 这里的括号没有什么特别之处。这也是非法的:for ((int ii = 0); ii &lt; 42; ++ii) { ... }。有时添加明显多余的括号会将有效语法更改为无效语法。

标签: c++ iso control-structure


【解决方案1】:

在条件中声明和初始化变量与在其他地方声明变量的区别在于,变量用作条件,并且在 if 的条件语句的范围内,但在条件之外的范围之外。此外,在 if 条件中重新声明变量是不合法的。所以

bool x=something();
if(x) {
    bool y=x; // legal, x in scope
    int x=3; // legal
    ...
}
while (x=something_else()) // legal, x still in scope
...

但是:

if(bool x=something()) 
    bool y=x; // still legal
    int x=3; // not legal to redeclare
    ...
}
while (x=something_else()) // x declared in condition not in scope any more

【讨论】:

    【解决方案2】:

    根据标准,在控制结构中声明变量与在其他地方声明变量之间的行为有什么区别?我似乎找不到任何提及它。

    控制结构介绍中的声明与其他地方的声明没有什么不同。这就是为什么你找不到任何差异的原因。

    6.4/3 确实为此描述了一些特定的语义,但并不奇怪:

    [n3290: 6.4/3]: 条件中的声明引入的名称 (由 type-specifier-seq 或 条件)在其声明点到结束的范围内 由条件控制的子语句。如果名字是 在子语句的最外层块中重新声明 条件,重新声明名称的声明格式不正确。 [..]


    另外,是否有任何技术原因说明为什么在使用此语法代替条件时没有给出任何特殊行为?例如,添加一组额外的括号会导致编译器错误;这也可以防止变量与其他条件链接。

    if 条件可以包含或者声明性语句表达式。任何表达式都不能包含声明性语句,因此也不能混合使用。

    [n3290: 6.4/1]: 选择语句选择多个控制流之一。

    selection-statement:
        if ( condition ) statement
        if ( condition ) statement else statement
        switch ( condition ) statement
    condition:
        expression
        attribute-specifier-seq[opt] decl-specifier-seq declarator = initializer-clause
        attribute-specifier-seq[opt] decl-specifier-seq declarator braced-init-list
    

    这一切都是从语法产生而来的。

    【讨论】:

    • 很多使用没有(或不能使用)使用新标准的编译器。此语法在 C++03 中是非法的。
    • 有些语法在 C++03 中是非法的,也就是说。 C++11 添加了braced-init-list
    • 好的,但结论成立。
    猜你喜欢
    • 1970-01-01
    • 2015-11-09
    • 2011-04-04
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多