Форум » C/C++ » Пример вычурной, но совершенно корректной конструкции С++. » Ответить

Пример вычурной, но совершенно корректной конструкции С++.

Сыроежка: Как известно С++ позволяет писать вычурные синтаксические конструкции, которые являются корректными с точки зрения стандарта С++, несмотря на то, что выглядеть могут они достаточно странно. Можно быо бы собрать коллекцию таких вычурных конструкций. Одну такую конструкцию, которую я придумал, я и хочу предложитть на ваше рассмотрение. Сначала небольшой экскурс в теорию С++. Точка объявления имени в С++ сразу же следует после завершения ее декларатора. Что это оозначает? В следующем объявлении int x = выражение; Имя x становится видным в выражении в правой части объявления, так как декларатор для x совпадает с ее именем. Поэтому в следующем примере значение переменной x, объявленной во внутреннем блоке, будет неопределенным: [pre2]int x = 12; { int x = x; }[/pre2] В предложении int x = x; в правой части используется имя переменной, декларатор которой уже объявлен в левой части объявления. А потому внешняя переменная x уже будет скрыта в правой части после знака присваивания. Другой пример: [pre2]const int i = 2; { int i[ i ]; }[/pre2] В этом случае в качестве размера массива будет использоваться внешняя переменная i, так как декларатор представляет из себя i[ i ] То есть пока декларатор не завершен, объявляемое имя еще не видно. А это означает, что внешняя переменная с именем i будет видна, и поэтому будет обявлен массив с двумя элементами. Эти примеры я взял из сттандарта С++. Теперь можно продемонстрировать придуманный мною вычурный пример инициализации переменной при ее объявлении через саму себя. [pre2]#include <iostream> int main() { int x = ( std::cin >> x, x ); std::cout << "x = " << x << std::endl; }[/pre2] В этом примере объявление переменной x совершенно корректно, и переменная получит вполне определенное значение, которое вы введете через консоль. Чтобы в этом убедиться, проанализируем эту конструкцию int x = ( std::cin >> x, x );. Имя x сразу же становится видным в правой части объявления после знака присваивания. В этой правой части используется выражение с оператором запятая. Сначала выполняется ввод значения через стандартный поток std::cin . Оператор запятая гарантирует, что имеется точка последовательности вычисления после запятой. Поэтому в память переменной x будет записано то, что будет введено. Ну, а так как что-то должно быть присвоено переменной x, так как указан оператор присваивания, то в операторе запятая снова указывается сама переменная x. Выглядет это вычурным, но тем не менее совершенно корректным.

Ответов - 1

Сыроежка: Вот простой пример использования такого вычурного определения переменной в программе вывода на консоль неотрицательного числа в обратном порядке следования его цифр (MS VC++ 2010): [pre2] #include "stdafx.h" #include <iostream> #include <functional> int _tmain(int argc, _TCHAR* argv[]) { std::function<void( unsigned int )> reverse = [&]( unsigned int x ) { std::cout << x % 10; ( x /= 10 ) ? reverse( x ) : void( std::cout << std::endl ); }; while ( unsigned int x = ( std::cout << "\nEnter a non-negative number (0 - exit): ", std::cin >> x, x ) ) { reverse( x ); } return 0; }[/pre2]



полная версия страницы