Como eu digito um ponteiro de função com o C ++ 11 usando sintaxe?


171

Eu gostaria de escrever isso

typedef void (*FunctionPtr)();

usando using. Como eu faria isso?


2
muito confuso using, principalmente porque os identificadores de ponteiros de função geralmente residem no meio de uma typedefinstrução e movem-se para a frente usando using. Pelo menos é onde estou perdido.
starturtle

Respostas:


180

Tem uma sintaxe semelhante, exceto que você remove o identificador do ponteiro:

using FunctionPtr = void (*)();

Aqui está um exemplo

Se você quiser "tirar a feiura", tente o que Xeo sugeriu:

#include <type_traits>

using FunctionPtr = std::add_pointer<void()>::type;

E aqui está outra demonstração .


25
Dang, eu esperava que iria tirar a feiúra:(
rubenvb

10
@rubenvb:; using FunctionPtr = AddPointer<void()>;)
Xeo

2
É possível usar aliases de tipo de modelo para limpar ainda mais add_pointer<void()>::type: Usando a sugestão aqui: groups.google.com/a/isocpp.org/d/msg/std-proposals/xDQR3y5uTZ0/…, você pode escrever pointer<function<void>>.
bames53

5
Esses aliases de tipo alteram a sintaxe do tipo de obscura, de dentro para fora, para uma sintaxe simples da esquerda para a direita, o que elimina amplamente a necessidade de typedefs personalizados para APIs específicas que facilitam a gravação dos tipos compostos da API.
bames53

10
No C ++ 14, você poderá escrever: using FunctionPtr = std :: add_pointer_t <void ()>;
Andrzej

46

A "feiúra" também pode ser removida se você evitar digitar um ponteiro:

void f() {}
using Function_t = void();    
Function_t* ptr = f;
ptr();

http://ideone.com/e1XuYc


Essa é uma abordagem interessante, embora eu possa estar preocupado em esquecer a *mais tarde e obter erros confusos.
Apollys suporta Monica

Esta é definitivamente a versão mais legal apresentada aqui. Obrigado. E eu prefiro ver um ponteiro, pois afinal é um ponteiro de função.
Pierre

13

Você deseja um type-id, que é essencialmente exatamente o mesmo que uma declaração, exceto que você exclui o declarator-id. O declarator-idgeralmente é um identificador e o nome que você está declarando na declaração equivilant.

Por exemplo:

int x

O declarator-idé xapenas removê-lo:

int

Da mesma forma:

int x[10]

Remova o x:

int[10]

Para o seu exemplo:

void (*FunctionPtr)()

Aqui declarator-idestá o FunctionPtr. então remova-o para obter o type-id:

void (*)()

Isso funciona porque, dado a, type-idvocê sempre pode determinar exclusivamente para onde o identificador iria para criar uma declaração. De 8.1.1 no padrão:

É possível identificar exclusivamente a localização no [ID do tipo] onde o identificador apareceria se a construção fosse uma [declaração]. O tipo nomeado é então o mesmo que o tipo do identificador hipotético.


9

Que tal esta sintaxe para maior clareza? (Observe parênteses duplos)

void func();
using FunctionPtr = decltype((func));

1
O que significam os parênteses duplos neste contexto? Uma referência a um ponteiro de função?
0x499602D2

5
Seu FunctionPtrnão é um ponteiro de função, mas decltype(&f)é, veja aqui .
Rubenvb 17/05

@ 1234597890 FunctionPtr é uma referência lvalue não-const para o tipo 'void ()'
Leo Goodstadt

@rubenvb: Você está certo. Não é um ponteiro de função, mas uma referência de valor à função (tipo). É por isso que static_assert falha ... <br/> Tente usar o FunctionPtr: using namespace std; #include <iostream> void do_f () {cerr << "o quê? \ n"; } void f (); usando FunctionPtr = decltype ((f)); usando FunctionPtr2 = decltype (& f); // Não funciona // usando FunctionPtr3 = decltype (f); int main () {FunctionPtr ff = do_f; ff (); FunçãoPtr2 ff2 = do_f; ff2 (); }
Leo Goodstadt 13/06/2013

1

Outra abordagem pode usar o tipo de retorno automático com o tipo de retorno à direita.

using FunctionPtr = auto (*)(int*) -> void;

Isso tem a vantagem discutível de poder dizer que algo é uma função ptr quando o alias começa com "auto (*)" e não é ofuscado pelos nomes dos identificadores.

Comparar

typedef someStructureWithAWeirdName& (FunctionPtr*)(type1*, type2**, type3<type4&>);

com

using FunctionPtr = auto (*)(type1*, type2**, type3<type4&>) -> someStructureWithAWeirdName&;

Disclaimer: Eu peguei isso da palestra "Easing into Modern C ++" de Bean Deane

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.