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:
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:
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.
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.
usingFunctionPtr=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.
using
, principalmente porque os identificadores de ponteiros de função geralmente residem no meio de umatypedef
instrução e movem-se para a frente usandousing
. Pelo menos é onde estou perdido.Respostas:
Tem uma sintaxe semelhante, exceto que você remove o identificador do ponteiro:
Aqui está um exemplo
Se você quiser "tirar a feiura", tente o que Xeo sugeriu:
E aqui está outra demonstração .
fonte
:(
using FunctionPtr = AddPointer<void()>;
)add_pointer<void()>::type
: Usando a sugestão aqui: groups.google.com/a/isocpp.org/d/msg/std-proposals/xDQR3y5uTZ0/…, você pode escreverpointer<function<void>>
.A "feiúra" também pode ser removida se você evitar digitar um ponteiro:
http://ideone.com/e1XuYc
fonte
*
mais tarde e obter erros confusos.Você deseja um
type-id
, que é essencialmente exatamente o mesmo que uma declaração, exceto que você exclui odeclarator-id
. Odeclarator-id
geralmente é um identificador e o nome que você está declarando na declaração equivilant.Por exemplo:
O
declarator-id
éx
apenas removê-lo:Da mesma forma:
Remova o
x
:Para o seu exemplo:
Aqui
declarator-id
está oFunctionPtr
. então remova-o para obter otype-id
:Isso funciona porque, dado a,
type-id
você sempre pode determinar exclusivamente para onde o identificador iria para criar uma declaração. De 8.1.1 no padrão:fonte
Que tal esta sintaxe para maior clareza? (Observe parênteses duplos)
fonte
FunctionPtr
não é um ponteiro de função, masdecltype(&f)
é, veja aqui .Outra abordagem pode usar o tipo de retorno automático com o tipo de retorno à direita.
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
com
Disclaimer: Eu peguei isso da palestra "Easing into Modern C ++" de Bean Deane
fonte