구문을 사용하여 C ++ 11로 함수 포인터를 typedef하는 방법은 무엇입니까?


171

나는 이것을 쓰고 싶다

typedef void (*FunctionPtr)();

사용하여 using. 어떻게해야합니까?


2
using특히 함수 포인터 식별자는 일반적으로 typedef명령문 중간에 상주하고를 사용하여 맨 앞으로 이동하기 때문에 매우 혼동 됩니다 using. 적어도 내가 잃어버린 곳입니다.
starturtle 2016 년

답변:


180

포인터에서 식별자를 제거한다는 점을 제외하면 비슷한 구문이 있습니다.

using FunctionPtr = void (*)();

여기에 예가 있습니다

"추악함을 없애고 싶다면"Xeo가 제안한 것을 시도해보십시오.

#include <type_traits>

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

그리고 여기 또 다른 데모가 있습니다.


25
Dang, 나는 그것이 추악함을 없애기를 바랐다:(
rubenvb

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

2
템플릿 유형 별칭을 사용하여 추가 정리가 가능합니다 add_pointer<void()>::type. 제안 사항 사용 : groups.google.com/a/isocpp.org/d/msg/std-proposals/xDQR3y5uTZ0/… 쓸 수 있습니다 pointer<function<void>>.
bames53

5
이러한 유형 별명은 유형 구문을 불명확 한 내부 구문에서 간단한 왼쪽에서 오른쪽 구문으로 변경하여 해당 API의 복합 유형을보다 쉽게 ​​작성할 수 있도록 특정 API에 대한 사용자 정의 typedef가 필요하지 않습니다.
bames53

10
C ++ 14에서는 다음과 같이 작성할 수 있습니다. using FunctionPtr = std :: add_pointer_t <void ()>;
Andrzej

46

포인터를 typedef하지 않는 경우 "추악함"을 제거 할 수도 있습니다.

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

http://ideone.com/e1XuYc


이것은 흥미로운 접근법이지만 *나중에 잊어 버리고 혼란스러워하는 오류가 발생할 수 있습니다.
Apollys는 Monica

이것은 여기에 제시된 가장 좋은 버전입니다. 감사합니다. 그리고 결국 함수 포인터이므로 포인터를 보는 것이 좋습니다.
피에르

13

type-id를 삭제한다는 점을 제외하면 선언과 정확히 동일한를 원합니다 declarator-id. 은 declarator-id일반적으로 식별자이며, 이름은 당신이 equivilant 선언에 선언되어있다.

예를 들면 다음과 같습니다.

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

5
귀하 FunctionPtr는 함수 포인터가 아니지만 여기를decltype(&f) 참조 하십시오 .
rubenvb

@ 1234597890 FunctionPtr은 'void ()'유형에 대한 상수가 아닌 lvalue 참조입니다.
Leo Goodstadt

@rubenvb : 맞습니다. 함수 포인터가 아니라 함수 (유형)에 대한 lvalue 참조입니다. static_assert가 실패하는 이유는 ... <br/> FunctionPtr을 사용해보십시오 : using namespace 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 2016 년

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.