2011-09-22 2 views
1

함수에 대한 포인터를 벡터 보류 상태로 만들려고합니다. 포인터는 나중에 secuentially라고합니다.
그래서 세 가지 기능이 있다고 가정 해 보겠습니다. int a(), void b();bool c();void 포인터를 함수의 형식과 함께 저장하려고합니다.

내 벡터 vector<void *> vec;

그리고 함수에 대한 포인터를 저장 내 기능입니다. 모든 기능이 저장 호출 할 때 그들은 모두 무효 포인터이기 때문에

void registerFunction(void *func) 
{ 
    vec.push_back(func); 
} 

이제 내 문제는 내가 그들의 유형을 모른 채 함수를 호출 할 수있다.

그래서 내 질문은 ... 내가 기호를 저장할 수있는 방법이있다 그래서 그들 각각의 포인터를 관련시킬 수있는 다음 함수에 void 포인터를 호출 할 때 형 변환?

: 함수는 항상 예를 ​​들어, void (*)(), 나는 따라서, 또한 예를 방법을 추가 할 것이다 유형이 될 수 없습니다. void (someclass::)(). 너무 많은 것을 요구하고 있습니까? 작동해야합니까?

+0

"기능에 대한 void 포인터"- 말단의 모순. (당신이 할 수있는 대부분의 메모리 주소에 해당하는,하지만 그때 당신은 C + + 사양을 떠난 것입니다) – sehe

답변

0

void*은 일반 함수 포인터 유형으로 안전하게 사용할 수 없습니다 (멀리 도망 갈 수도 있지만).

그러나 모든 함수 대 포인터 값은 다른 포인터 대 함수 유형으로 변환 될 수 있으며 정보를 잃지 않고 다시 되돌릴 수 있습니다. 따라서 예를 들어 void (*)() (void를 반환하고 아무런 인수도 사용하지 않는 함수에 대한 포인터)를 일반 함수 포인터 유형으로 사용할 수 있습니다.

유형을 저장하는 데있어 가능한지 확실하지 않습니다. 제한된 수의 가능성이있는 경우 열거 유형과 switch 문을 사용할 수 있습니다.

하지만 상속에 기반한 디자인을 사용하는 것이 더 나을 것입니다.

4

함수 포인터를 void*으로 변환 할 수 없습니다. 허용되지 않습니다.

모든 함수를 0 인수로 호출 할 수 있고 반환 형식을 신경 쓰지 않으면 (function은 C++ 표준 라이브러리에서 지원하지 않으면 Boost 및 TR1에서도 찾을 수 있습니다).

template <typename T> 
struct ignore_result_impl 
{ 
    ignore_result_impl(T fp) : fp_(fp) { } 
    void operator()() { fp_(); } 
    T fp_; 
}; 

template <typename T> 
ignore_result_impl<T> ignore_result(T fp) 
{ 
    return ignore_result_impl<T>(fp); 
} 

int g() { return 42; } 
std::function<void()> f(ignore_result(g)); 

(부스트 구현에서 :

내가 올바르게 기억

비록, 반환 타입 변환이 경우 다음과 같은 것을해야 할 수는 C++ 11 std::function 구현에서 허용되지 않습니다 나는 당신이 function<void()>을 직접 사용할 수 있다는 것을 알고 있지만 C++ 11에서는 더 이상 허용되지 않는다고 확신한다. 나는 틀릴 수도 있고, 누군가가 알고있는 경우 주석의 설명을 이해할 수있을 것이다.)

+2

나는 그것이 실제로 허용 (즉, 그것은 제약 위반 아니에요),하지만 행동뿐만 아니라 결과)는 정의되지 않습니다. 적어도 그것은 C의 경우입니다. C++은 다를 수 있습니다. –

+0

@KeithThompson이 정의되지 않은 것은 허용되지 않는 것과 거의 같습니다. –

+0

@ R.MartinhoFernandes : 나는 그렇게 말하지 않을 것입니다. 구현시 진단해야하는 오류 (구문 오류와 제약 조건 위반)와 그렇지 않은 오류 사이에는 큰 차이가 있습니다. 구별을 이해하는 것이 가장 중요하지 않습니다. 그리고 때로는 코드화가 필요하지 않습니다. 그러한 코드는 표준에 의해 * 정의되지 않은 것들을 일상적으로 수행하지만, 다른 것으로 정의 될 수도 있습니다. 예를 들어, POSIX'dlsym' 함수는'void *'를 함수 포인터로 변환하는 능력에 달렸습니다. –

0

As 모든 함수가 동일한 형식 시그니처를 따르는 한 void 포인터를 해당 유형으로 다시 캐스트 할 수 있습니다.

typedef int(*fun_ptr)(); 
vector<fun_ptr> vec; 

그런 다음 당신은 캐스트가 필요하지 않습니다

더 나은 솔루션 기능 유형을 형식 정의를하는 것입니다.

+0

+1 fun_ptr 아이디어입니다. -1 포인터를 다시 사용할 수 있다고 말하면 -1 (네가 캐스팅 할 수 있고, 다시 '뭔가'를 캐스팅한다고 주장 할 수 없으며, '무언가'로 캐스팅합니다 - 정의되지 않음) – sehe

관련 문제