您编写的表达式p++ 位于命名空间范围内。 §7.3.1/1 中定义的 namespace-body 的语法是禁止的:
命名空间主体:
声明序列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,这意味着我不能写下面的(see error):
any a1 = f(10,10); //error
这就是我使用 comma 运算符的原因,以便表达式可以具有一些值,该值的计算结果是逗号表达式中的最后一个操作数。对于std:cout,由于它返回std::ostream&,我不需要使用逗号运算符;没有它也没关系。
上面代码中还有一个有趣的地方:为什么我在里面定义了any 和一个templated 构造函数?答案是,我写这个是为了给 any 类型的值赋值(不是双关语),无论是int、std::ostream& 还是其他。 templated 构造函数可以接受任何类型的参数。
但是不要写这样的代码。它们不能保证按您期望的方式工作。
阅读本主题中的答案,您会明白为什么这种编码可能很危险: