2

g++ 在匿名实例创建中使用先前声明的变量时会出现重新声明错误。

我的“weird.cpp”源文件中有以下代码:

#include <iostream>

int main()
{
  int i = 0;
  int j = int ( i );
  int ( i );
}

我得到的错误是,

weird.cpp: In function ‘int main()’:
weird.cpp:7: error: redeclaration of ‘int i’
weird.cpp:5: error: ‘int i’ previously declared here

我已经分别在 4.2 和 4.7 版本的 mac 和 linux 中尝试过这个。我也尝试过使用其他类型而不是 int。结果是同样的错误。谁能帮我理解这个问题?谢谢。

4

2 回答 2

2

首先,您在这里使用的括号没有任何作用。

int i = 0;
int j = int(i); // This is casting i to an int. It's already an int.
int j = i; // This does the same as the last line.
int (i); // This is redeclaring an int named i, which had already been done.
int i; // This is the same as the last line.

您所说的关于int在其构造函数中接受一个对象的内容是没有意义的。

struct A { A(int) {} };
int i;
A obj(i); // A instance named obj which takes integer i as constructor argument.

我真的不明白你想在这里实现什么,也许是这个?

int i = 0;
int j = i;
{
    int i; // In another scope, shadowing the first i for scope duration.
}
于 2013-09-26T04:43:35.920 回答
2

您对此感到困惑是可以原谅的,这是 C++ 的上下文敏感特性以及编译器如何解释它的一个例子。

int (i);

被视为“i”的声明(并且由于您在此范围内已经有一个名为 i 的变量并且尚未启用 -Wno-shadow,因此不允许这样做)。

与以下无法编译的情况对比:(请参阅http://ideone.com/QuwnTC

#include <iostream>

class Bark {
public:
    Bark(const char* msg, const char*) {
         std::cout << "Hear ye, hear ye. " << msg << std::endl;
    }
};

void bark(const char* i) {
    Bark (i); // error here.
}

int main(int argc, const char* argv) {
    bark("wtf");
}

它抱怨 Bark (i) 掩盖了“i”的声明。

但是,以下两个都可以编译:http: //ideone.com/dcGMET

void bark(const char* i) {
    Bark (i + 1);
}

或在括号内有两个参数:(http://ideone.com/tMzSY9

#include <iostream>

class Bark {
public:
    Bark(const char* msg, const char*) {
         std::cout << "Hear ye, hear ye. " << msg << std::endl;
    }
};

void bark(const char* i) {
    Bark (i, NULL);
}

int main(int argc, const char* argv) {
    bark("wtf");
}

显然,这里对“类型(名称)”的处理是某种特殊情况,您可能想向编译器开发人员提出这个问题。

于 2013-09-26T06:58:17.293 回答