与在GCC中使用声明编译相同范围内的类声明但不是MSVS

时间:2015-07-04 11:36:09

标签: c++ declaration language-lawyer using-declaration

以下程序是否符合c ++标准?

namespace X { class A; }

namespace Y { using X::A; class A {}; }

int main() {}

我使用不同的编译器获得了不同的结果:

  • gcc编译它没有错误。
  • visual c ++给出错误C2888:'X :: A':无法在命名空间'Y'中定义符号

我发现我的程序违反了c ++标准中的任何规则。

如果程序格式正确,为什么visual studio会出错?

如果程序格式不正确,c ++标准中的规则是否违反了,为什么gcc没有出错?

我不是想让我的程序编译。我只是想根据c ++标准找出它是否格式正确以及我测试的两个编译器为什么表现不同。

2 个答案:

答案 0 :(得分:4)

我认为该计划形成不良。 [basic.scope.declarative] / 4说:

  

在单个声明性区域中给出一组声明,每个声明都指定相同的非限定名称,

     

- 它们都应引用同一个实体,或全部引用功能和功能模板;或

     

- 正好一个声明应声明一个不是typedef名称的类名或枚举名,其他声明都应引用相同的变量或枚举,或者全部引用函数和函数模板;在这种情况下,类名或枚举名称是隐藏的

非限定名称int index = (int)[self.messages indexOfObject:self.messageToDelete]; [self.messages removeObject:self.messageToDelete]; NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0]; [tableView beginUpdates]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft]; [tableView endUpdates]; 的两个声明引用不同的实体,这两个实体都是类。

(有趣的是,GCC 6.0和Clang 3.7似乎都没有这样诊断。两者都接受编写的代码(不诊断具有相同名称的两个不同类的声明)。如果你将int index = (int)[self.messages indexOfObject:self.messageToDelete]; [self.messages removeObject:self.messageToDelete]; NSIndexPath *indexPath = [NSIndexSet indexSetWithIndex:0]; [tableView beginUpdates]; [tableView deleteSections:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft]; [tableView endUpdates]; 添加到A的主体,然后Clang抱怨X::A a;的不完整类型。)

答案 1 :(得分:-2)

不太确定,但你可以尝试这样的事情:

namespace X { class A; }

namespace Y 
{
  class X::A {}; 
}

int main() 
{
  return 0;
}