Выражение p++
, которое вы написали, находится в области имен. Это запрещено грамматикой тела-пространства имен , которое определено в §7.3.1 / 1 как:
Пространство имен тела:
Заявление-сл неавтоматического
, который говорит, что тело пространства имен может опционально содержать только объявление . И 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&
или что-то еще. Конструктор templated может принимать аргументы любого типа.
Но не пишите такой код. Они не гарантированно работают так, как вы ожидаете.
Прочтите ответы в этой теме, чтобы узнать, почему такое кодирование может быть опасным: