关于标准中哪条规则的任何想法都说明了这样的陈述:
p++; //where 'p' is pointer to array
不能出现在全球范围内?
如果可能的话,我正在寻找一个参考,而不仅仅是一个解释。
答案 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
请注意f()
的返回类型为void
,这意味着我无法编写以下内容(see error):
any a1 = f(10,10); //error
这就是为什么我使用逗号运算符以便表达式可以有一些值,它会计算到逗号表达式中的最后一个操作数。如果是std:cout
,因为它返回std::ostream&
,我不需要使用逗号运算符;没有它就好了。
上面的代码中还有一个有趣的事情:为什么我在其中定义了any
和模板化构造函数?答案是,我写了这个,以便我可以分配任何类型的值(没有双关语意),无论是int
,std::ostream&
还是其他什么。 模板构造函数可以接受任何类型的参数。
但是不要写这样的代码。他们无法保证以您期望的方式工作。
阅读本主题中的答案,您将看到为何此类编码可能存在危险:
答案 1 :(得分:0)
通过说“这样的陈述”我想你知道/为什么一般的陈述不能在全球范围内。
p++;
是一个声明,因为它基本上被翻译成:
p = p + 1;
这是一个正常的陈述。
答案 2 :(得分:0)
当然是Stroustrup的“C ++编程语言”。
第r.6.1节讨论了语句 - 可以是标签,表达式,复合语句,选择语句,迭代语句,跳转语句或声明语句。
然后跳回3.3.1节,其中显示了语句的语法和参考: 注意.....没有赋值语句或过程调用语句。赋值和函数调用作为表达式处理。
第r.3.1节然后讨论了四种类型的范围 - 本地,函数,文件和类。因为全局基本上是“文件”范围。在全局范围内允许使用名称,就像在返回或参数类型中首次声明的类一样。
真的找不到具体的确定性,说明你不能在全球范围内有一个表达式声明,但遗漏的是参考文献显示你可以拥有的东西。