为什么语句不能出现在命名空间范围内?

时间:2011-12-12 04:49:31

标签: c++ compiler-errors standards

关于标准中哪条规则的任何想法都说明了这样的陈述:

p++; //where 'p' is pointer to array

不能出现在全球范围内?

如果可能的话,我正在寻找一个参考,而不仅仅是一个解释。

3 个答案:

答案 0 :(得分:12)

您编写的表达式p++位于命名空间范围内。 namespace-body 的语法禁止使用,该语法在§7.3.1/ 1中定义为:

  

名称空间结构体:
  声明-SEQ <子>选择

表示命名空间主体可选只包含 声明p++肯定不是声明,它是一个表达式,因此标准隐含地禁止它。标准可能有明确的声明禁止这一点,但我认为上述内容应该足够了。

以同样的方式,不能执行此操作:

namespace sample
{
  f(10,10); //error
  std::cout << "hello world" << std::endl;//error
}

但如果您将表达式转换为声明(或者更确切地说在声明中使用表达式),那么您可以评估所谓的表达式。这是一招:

#include<iostream>

namespace sample
{
  struct any { template<typename T> any(const T&){} };

  void f(int a,int b) { std::cout << a * b <<  std::endl; }

  any a1= (f(10,10), 0); //ok
  any a2 = std::cout << "hello world" << std::endl;//ok
}

int main() {}

输出(如果你很幸运):

100
hello world

在线演示:http://ideone.com/icbhh

请注意f()的返回类型为void,这意味着我无法编写以下内容(see error)

any a1 = f(10,10); //error

这就是为什么我使用逗号运算符以便表达式可以有一些值,它会计算到逗号表达式中的最后一个操作数。如果是std:cout,因为它返回std::ostream&,我不需要使用逗号运算符;没有它就好了。

上面的代码中还有一个有趣的事情:为什么我在其中定义了any模板化构造函数?答案是,我写了这个,以便我可以分配任何类型的值(没有双关语意),无论是intstd::ostream&还是其他什么。 模板构造函数可以接受任何类型的参数。

但是不要写这样的代码。他们无法保证以您期望的方式工作。

阅读本主题中的答案,您将看到为何此类编码可能存在危险:

答案 1 :(得分:0)

通过说“这样的陈述”我想你知道/为什么一般的陈述不能在全球范围内。

p++;

是一个声明,因为它基本上被翻译成:

p = p + 1;

这是一个正常的陈述。

答案 2 :(得分:0)

当然是Stroustrup的“C ++编程语言”。

第r.6.1节讨论了语句 - 可以是标签,表达式,复合语句,选择语句,迭代语句,跳转语句或声明语句。

然后跳回3.3.1节,其中显示了语句的语法和参考: 注意.....没有赋值语句或过程调用语句。赋值和函数调用作为表达式处理。

第r.3.1节然后讨论了四种类型的范围 - 本地,函数,文件和类。因为全局基本上是“文件”范围。在全局范围内允许使用名称,就像在返回或参数类型中首次声明的类一样。

真的找不到具体的确定性,说明你不能在全球范围内有一个表达式声明,但遗漏的是参考文献显示你可以拥有的东西。