声明中类型和对象的相同标识符

时间:2017-08-04 09:32:55

标签: c++ c naming-conventions variable-declaration function-definition

我偶然发现了一个函数实现,该函数实现为同一类型的参数回收类型名称。代码编译并且似乎完全符合预期。这是一个最小化的版本:

#include <iostream>

using namespace std;

struct X {
    int v;
};

void print_X(const X& X)   // <--- here the identifier X has *two different meanings*
{
    cout << "X.v:" << X.v << endl;
}

该代码是针对Borland C ++ 5.6.4开发的。

我尝试了几种不同的,更新的编译器:

所有人都毫无怨言地接受它。

我认为这不是很好的C ++,但是......

C ++是否有效?并且,如果是,它将来是否有效?

更新

多么可怕!只有现在我看到,对于一个简单的变量声明也是如此:

X X;

演示:http://ideone.com/a9GM49

更新#2

C ++与C语言共享此功能:

#include <stdio.h>

typedef struct X {
    int v;
} X;

int main()
{
    X X;
    X.v = 7;
    printf("X.v:%d\n", X.v);
    return 0;
}

演示:http://ideone.com/nheZTa

3 个答案:

答案 0 :(得分:2)

是的,它是有效的。您在内部作用域中声明了一个变量(参数),该变量(参数)隐藏了外部作用域中的名称。

在这种情况下当然不是一个好主意。

答案 1 :(得分:2)

有效。它隐藏了外部范围的变量。像这样隐藏通常被称为 shadowing ,你的编译器可能会发出警告,你可以告诉你它何时发生(gcc有$productId = $_POST['product_id']; $product = wc_get_product( $productId ); //print_r($product); $image = wp_get_attachment_image_src( get_post_thumbnail_id( $productId ), 'single-post-thumbnail' ); $product_data .='<div class="row"><div class="col-sm-12">'; $product_data .='<img src="'.$image[0].'">'; $product_data .= '<h4 class="title">'.$product->get_title().'</h4>'; $product_data .= '<p class="prodis">'.apply_filters( 'the_content', get_post_field('post_content', $productId) ).'</p>'; $product_data .= '<p class="proprice">'.$product->get_price_html().'</p>'; $product_data .= '<p class="addcardft">'.do_action('woocommerce_simple_add_to_cart').'</p>'; $product_data .='</div></div>'; echo $product_data; )。

这是另一个例子:

-Wshadow

但要尽量避免做上述事情。它很快就会导致混乱和错误。

答案 2 :(得分:1)

通过这样做,您可以在功能块中隐藏全局名称。

void print_X(const X& X, const X& Y)  //won't compile

void print_X(const X& X){
   X myX;    //again, won't compile
}

在Stroustrup中: *

  

块中名称的声明可以隐藏声明   封闭块或全局名称。也就是说,名称可以重新定义为   引用块内的不同实体。退出街区后,   这个名字恢复了之前的含义。

* Stroustrup:C ++编程语言,第4版;第6.3.4节范围;第157页