2010-06-02 5 views
2

일부 C 및 C++ 라이브러리를 믹싱하고 있으며 콜백 함수로 작업 할 수있는 포인터가 하나뿐입니다. 내가해야 할 일은 벡터를 반복하는 것뿐입니다. 이 함수는 C++에서 extern "C" 블록되어컨테이너없이 반복자 사용하기


bool call_back(void* data){ 
    done=... 
    if (!done) cout << *data++ << endl; 
    return done; 
} 

주 : 여기 간략화 안된 예이다. call_back은 true가 반환 될 때까지 호출됩니다. 그것이 호출 될 때마다 다음 요소를 알아 내고 싶습니다. data은 코드의 다른 곳에서 전달할 수있는 포인터입니다 (위의 예제에서 반복자이지만 다른 것일 수 있음). data의 내용은 done을 계산하는 데 사용됩니다.

  1. 내 벡터에 data 지점이 : 나는 data에주는 두 가지 명백한 옵션을 참조하십시오.
  2. data은 내 벡터의 반복기를 가리 킵니다.

.end() 메서드를 사용할 수 없으면 이터레이터를 사용할 수 없습니다. 맞습니까? 어쩌면 내가 그 데이터를 제거하기 시작하면 않는 한 벡터 혼자 사용할 수 없습니다. vector와 iterator로 구조체를 만들 수 있지만 더 좋은 방법이 있습니까? 너는 무엇을 할 것이냐?

+0

이 함수는 C++ 코드에서만 호출됩니까? –

+0

예, C++ 코드 파일에서 항상 extern "C"가 될 것으로 예상합니다. – User1

답변

3

데이터가 필요한 모든 정보가있는 구조를 가리 키지 않는 이유는 무엇입니까?

이전의 "C"스타일 콜백에 대한 요점은 void *가 모든 객체를 가리킬 수 있다는 것입니다. 콜백 함수는 형식이 무엇인지는 알고 있지만 아무것도 될 수는 없습니다.

typedef struct Plop 
{ 
    std::vector<int>::iterator begin; 
    std::vector<int>::iterator end; 
} Plop; 

bool call_back(void* data) 
{ 
    // Or static_cast<> for the pedantic. 
    // I like reinterpret_cast<> because it is a clue to humans that this is dangerious 
    // and as long as the object was originally a Plop* pointer it is guaranteed to work. 
    Plop* info = reinterpret_cast<Plop*>(data); 

    bool done= info.begin == info.end; 

    if (!done) cout << *data++ << endl; 
    return done; 
} 
+0

이 함수를 위해서 새로운 구조체를 피하고 싶었습니다. 캐스팅에 대한 흥미로운 의견. – User1

0

이터레이터의 참조를 취소하고 그 값을 call_back으로 전달하는 것은 어떻습니까? 그런 다음 함수가 반환 된 후에 그것을 증가 시키시겠습니까?

1

.end() 메서드를 사용할 수 없으면 이터레이터를 사용할 수 없습니다. 맞습니까?

아니요. 반복기를 .end() 함수를 호출 한 결과와 함께 사용할 수 있습니다. .end() 함수를 계속 호출 할 필요가 없습니다 ... 그래서 두 개의 반복자 만 저장하면 황금이됩니다.

(데이터 제거를 시작하지 않는 한) 벡터를 사용할 수 없습니다.

std :: size_t 인덱스 만 있으면 충분합니다.

벡터와 반복기 모두를 사용하여 구조체를 만들 수 있지만 더 좋은 방법이 있습니까? 너는 무엇을 할 것이냐? 다른 컨테이너 유형을 지원에 대해 걱정할 필요가없는 경우

, 그럼 내가 사용합니다 :

template<typename T> struct CALLBACK_DATA 
{ 
     std::vector<T>* array; 
     std::size_t index; 
}; 

를 여러 컨테이너 유형을 지원해야 할 수도 있다면, 내가 사용하는 것이 :

template<typename T> struct CALLBACK_DATA 
{ 
    typedef std::vector<T> container_type; 
    typedef typename std::vector<T>::const_iterator const_iterator; 
    const_iterator current; 
    const_iterator end; 
}; 

그래, 나는 벡터와 인덱스 또는 반복자 쌍을 전달할 것이고 데이터를 보관하기 위해 구조체를 만들 것이다. 구조체를 만들지 않으려면 std::pair을 사용할 수 있지만 개인적으로이 정보를 저장하는 사용자 정의 구조체를 만드는 것이 더 읽기 쉽다고 생각합니다.