web-dev-qa-db-ja.com

構文を使用してC ++ 11で関数ポインタをtypedefするにはどうすればよいですか?

これを書きたい

typedef void (*FunctionPtr)();

usingを使用します。どうすればいいですか?

151
rubenvb

ポインタから識別子を削除することを除いて、同様の構文があります。

using FunctionPtr = void (*)();

「さを取り除きたい」場合は、Xeoが提案したことを試してください。

#include <type_traits>

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

そしてここに別の デモ があります。

161
0x499602D2

ポインタのtypedefingを回避する場合、「linesさ」も取り除くことができます。

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

http://ideone.com/e1XuYc

38
Vadim Goryunov

type-idが必要です。これは、declarator-idを削除する以外は、基本的に宣言とまったく同じです。 declarator-idは通常識別子であり、同名宣言で宣言する名前です。

例えば:

int x

declarator-idxなので、削除するだけです。

int

同様に:

int x[10]

xを削除します。

int[10]

あなたの例:

void (*FunctionPtr)()

ここで、declarator-idFunctionPtrです。削除してtype-idを取得してください:

void (*)()

これは、type-idを指定すると、宣言を作成するために識別子がどこに移動するかを常に一意に決定できるためです。標準の8.1.1から:

構造が[宣言]である場合に識別子が表示される[type-id]内の場所を一意に識別することができます。名前付きの型は、仮想識別子の型と同じです。

11
Andrew Tomazos

わかりやすくするために、この構文はどうですか? (二重括弧に注意)

void func();
using FunctionPtr = decltype((func));
9
Leo Goodstadt

別のアプローチでは、自動戻り型と末尾戻り型を使用する場合があります。

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

これには、エイリアスが「auto(*)」で始まり、識別子名で難読化されていないときに、何かを関数ptrであると伝えることができるという議論の余地があります。

比較する

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

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

免責事項:Bean Deaneの「Easing into Modern C++」トークからこれを取り上げました

1
Silvester