提问者:小点点

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


任何关于标准规则的想法,都会陈述如下:

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

不能显示在全局范围内?

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


共3个答案

匿名用户

您编写的表达式P++位于名称空间范围内。 在§7.3.1/1中,命名空间-主体的语法禁止使用:

命名空间-主体:
 ; ;nbsp; ;声明-序列opt

这说明命名空间主体可以选择只包含声明。 而且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,这意味着我无法编写以下内容(请参阅错误):

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

这就是为什么我使用逗号运算符,这样表达式可以有一些值,这些值的计算结果是逗号表达式中的最后一个操作数。 在std:cout的情况下,由于它返回std::Ostream&;,我不需要使用逗号运算符; 没有它也可以。

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

但是不要写这样的代码。 他们不能保证按照你期望的方式工作。

阅读本主题中的答案,您将了解为什么这样的编码可能是危险的:

  • main()真的是C++程序的开始吗?

匿名用户

通过说“statements like this”,我猜你知道为什么语句一般不能在全局范围内。

p++;

是一个语句,因为它基本上被翻译成:

p = p + 1;

这是正常的说法。

匿名用户

请参阅Stroustrup的“C++编程语言”。

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

然后跳回到第3.3.1节,它显示了语句语法和引用:注意。。。。。没有赋值语句或过程调用语句。 赋值和函数调用作为表达式处理。

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

真的找不到具体的定义,说明你不能在全局范围内有表达式语句,但是通过省略引用显示了你可以有什么。