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


171

これを書きたい

typedef void (*FunctionPtr)();

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


2
using特に、関数ポインタ識別子は通常、typedefステートメントの途中にあり、を使用して前に移動するため、非常に確信がありusingます。少なくともそれは私が迷っているところです。
スターター

回答:


180

ポインタから識別子を削除することを除いて、構文は似ています。

using FunctionPtr = void (*)();

ここに例があります

「醜さを取り除く」には、Xeoの提案を試してください。

#include <type_traits>

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

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


25
ダン、醜さを取り除くことを望んだ:(
rubenvb

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

2
テンプレートタイプエイリアスを使用してさらにクリーンアップすることができます。add_pointer<void()>::typeここの提案を使用してください:groups.google.com/a/isocpp.org/d/msg/std-proposals/xDQR3y5uTZ0/…と書くことができますpointer<function<void>>
bames53 2013年

5
これらの型エイリアスは、型構文を不明瞭なインサイドアウト構文から単純な左から右への構文に変更します。これにより、特定のAPIのカスタムtypedefが不要になり、そのAPIの複合型を簡単に記述できます。
bames53 2013年

10
C ++ 14では、次のように記述できます。FunctionPtr= std :: add_pointer_t <void()>;を使用します。
アンジェイ2013年

46

ポインタのtypedefを回避すると、「醜さ」を取り除くこともできます。

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

http://ideone.com/e1XuYc


これは興味深いアプローチですが、*後で忘れて混乱するエラーが発生するのではないかと心配になるかもしれません。
Apollysがモニカをサポートする

これは間違いなくここで紹介する最も良いバージョンです。ありがとうございました。そして、ポインタは関数ポインタなので、私はポインタを見ることを好みます。
ピエール

13

あなたは欲しいtype-id、本質的に削除を除いて、宣言とまったく同じです、declarator-iddeclarator-id通常、これは識別子であり、等価宣言で宣言する名前です。

例えば:

int x

declarator-idされるxので、それを削除します。

int

同様に:

int x[10]

を削除しxます:

int[10]

あなたの例のために:

void (*FunctionPtr)()

ここにdeclarator-idありFunctionPtrます。だからそれを削除してtype-idください:

void (*)()

これが機能するのは、与えられたtype-id識別子が宣言を作成する場所を常に一意に決定できるためです。標準の8.1.1から:

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


9

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

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

1
この文脈で二重括弧はどういう意味ですか?関数ポインタへの参照
0x499602D2 2013年

5
あなたFunctionPtrは関数ポインタではありませんdecltype(&f)が、ここを参照してください
rubenvb 2013年

@ 1234597890 FunctionPtrはタイプ 'void()'への非const左辺値参照
Leo Goodstadt

@rubenvb:その通りです。これは関数ポインタではなく、関数(型)への左辺値参照です。static_assertが失敗するのはこのためです... <br/> FunctionPtrを使用してみてください:名前空間stdを使用してください。#include <iostream> void do_f(){cerr << "what?\ n"; } void f(); FunctionPtr = decltype((f));を使用します。FunctionPtr2 = decltype(&f);を使用 //機能しません// FunctionPtr3 = decltype(f);を使用します int main(){FunctionPtr ff = do_f; ff(); FunctionPtr2 ff2 = do_f; ff2(); }
Leo Goodstadt 2013年

1

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

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 ++」の話からこれを取り入れました

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.