2013-02-13 2 views
4

8.3.5/8 Functions [dcl.fct] говоритНевозможно вернуть функцию из функции. Как я мог?

[...] функции не должна иметь тип возвращаемого типа массива или функции, хотя они могут иметь тип возвращаемого указателя типа или ссылки на такие вещи. [...]

Почему так явным правилом? Есть ли какой-то синтаксис, который бы даже позволял возвращать функцию в отличие от указателя на функцию?

Я пропустил перевод цитаты?

typedef void (*fp)(); 

void foo(){} 
fp goo() 
{ 
    return foo; //automatically converted to function pointer 
} 
+0

возвращение (аннулируются *) Foo !! –

+1

@ B.Nadolson, который считается недействительным. –

+1

"автоматически преобразуется в функцию ** указатель **". Тогда это не функция;) – mfontanini

ответ

3

Это довольно надуманный пример функции пытается вернуть функцию:

void foo() { } 

template<typename T> 
T f() { return foo; } 

int main(){ 
    f<decltype(foo)>(); 
} 

Это ошибка, я получаю от Clang 3.2:

Compilation finished with errors: 
source.cpp:7:5: error: no matching function for call to 'f' 
    f<decltype(foo)>(); 
    ^~~~~~~~~~~~~~~~ 
source.cpp:4:3: note: candidate template ignored: substitution failure 
[with T = void()]: function cannot return function type 'void()' 
T f() { return foo; } 
~^
1 error generated. 
+0

+1: Именно. Кроме того, это всего лишь один из тех редких случаев, когда C++ делает вещи ясными и явными для нас, а не оставляет нас для вывода из грамматики и других различных правил (например, несовместимости). Похвали его! –

+0

@LightnessRacesinOrbit: Действительно. Я часто чувствую, что выведение правила из Стандарта похоже на доказательство теоремы числовой теории. Не в этом дело. –

+1

Да; Интересно, что он достаточно редок, чтобы на самом деле генерировать SO-запрос от встревоженного OP, когда это происходит. –

1

Я знаю, что это, вероятно, не ответить на ваш вопрос полностью, но он делает это частично

Вы можете вернуть функцию из другой функции (это то, что лямбды есть)

std::function<int (int)> retLambda() { 
    return [](int x) { return x; }; 
} 
+0

Технически, лямбды не являются функциями, хотя они являются экземплярами * функторов * –

1

ли существует какой-то синтаксис, который даже позволяет возвращать функцию в отличие от указателя функции?

Синтаксис? Уверены, что есть:

using fun = int (int); 

fun function_that_returns_a_function(); 

Это не скомпилировано, потому что правило в §8.3.5/8 запрещает его использование. Я не знаю, почему правило конкретно существует, но учтите, что тип «функция» не имеет никакого размера, поэтому вы не можете создавать объекты типа функции в C++.