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

Why statements cannot appear at namespace scope?

本文关键字:命名空间 范围内 语句 不能 为什么      更新时间:2023-10-16

你知道标准中的哪条规则是这样表述的吗?

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

不能出现在全局作用域中?

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

您所编写的表达式p++位于名称空间范围内。命名空间-体的语法是禁止的,在§7.3.1/1中定义为:

namespace-body:
,,,, declaration-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,这意味着我不能写以下内容(见错误):

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

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

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

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

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

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

通过说"statements like this",我猜你知道/为什么语句一般不能在全局作用域中。

p++;

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

p = p + 1;

是一个正常的语句

查看Stroustrup的《c++编程语言》。

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

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

第r.3.1节接着讨论了四种作用域类型——局部作用域、函数作用域、文件作用域和类作用域。因为全局本质上是"文件"作用域。全局作用域允许使用名称,就像首先在返回值或参数类型中声明的类一样。

真的找不到具体的明确规定,明确指出不能在全局范围内使用表达式语句,但是通过省略引用显示了可以使用的内容。