Ценности – это функции! Примеры:
val(3)
val("Hello, World")
Первый оценивает нулевую функцию (функцию, не принимающую аргументов), которая возвращает int
, 3
. Второй оценивает до нулевой функции, которая возвращает char const(&)[13]
, "Hello, World"
.
Запутались? val
является унарной функцией и val(3)
вызывает его, говорите? Да. Однако внимательно прочитайте: "оценивает до нулевой функции". val(3)
оценивает до (возвращает) нулевую функцию. Aha! val(3)
возвращает функцию! Так, поскольку val(3)
возвращает функцию, вы можете вызвать ее. Пример:
std::cout << val(3)() << std::endl;
(См. values.cpp)
Второй вызов функции (без аргументов) вызывает нулевую функцию, которая затем возвращает 3
. Необходимость второго вызова функции является причиной, по которой функция называется Лациально оцененная. Первый звонок ничего не делает. Вам нужен второй звонок, чтобы наконец оценить ситуацию. Первый вызов лениво оценивает функцию, т.е. ничего не делает и откладывает оценку на потом.
Может быть не сразу видно, насколько ленивая оценка может быть полезна, просто взглянув на приведенный выше пример. Поместить первый и второй вызов функции в одну строку действительно не очень полезно. Однако, если рассматривать val(3)
как функцию обратного вызова (и в большинстве случаев они фактически используются таким образом), это будет ясно. Пример:
template <typename F>
void print(F f)
{
cout << f() << endl;
}
int
main()
{
print(val(3));
print(val("Hello World"));
return 0;
}
(См. callback.cpp)