2014-03-24 2 views
1

std::map 초기화하는 방법을 이해하려고합니다. 나는 this 잘 알려진 주제를 연구했으나, 오래된 gcc 및 부스트 버전 (gcc 4.4, 1.41 -> C++ 11 기능 향상은 제한적, boost::asign::map_list_of does not compile)을 사용하도록 강제 되었기 때문에 아무도 대답이 적합하지 않았습니다. , 나는 객체 생성시에 클래스 밖에서 그것을 할 필요가 있기 때문에 std :: map 초기화에 클래스 멤버 함수를 사용하고 싶지 않다.std :: pairs 배열 초기화 초기화 (포인터 오류?)

그러나,이 반복자를 받아 std::map의 생성자가 오버로드 (this 스레드가 너무 나에게 영감),이 내 해결 방법입니다 : 내가 BOOST_ASSERT 매크로와 함께 행의 주석을 해제하면

template <typename Arg, typename Callback> 
class CallbackSelector 
{ 
    private: 
     const std::map<Arg, Callback> Mapping; 

    public: 
     CallbackSelector(std::pair<Arg, Callback> _Mapping[]): 
      Mapping(_Mapping, _Mapping + sizeof(_Mapping)/sizeof(std::pair<Arg, Callback>)) 
      { 
       //BOOST_ASSERT(sizeof _Mapping)/(sizeof (std::pair<Arg, Callback>)) == 2); 
       std::cout << "sizeof _Mapping " << sizeof _Mapping << std::endl; 
       std::cout << "sizeof (std::pair<Arg, Callback>) " << sizeof (std::pair<std::string, boost::function<void(void)> >) << std::endl; 
      }; 
}; 

void PamEvent() {} 

void DefaultEvent() {} 

int main(int argc, char** argv) 
{ 
    std::pair<std::string, boost::function<void(void)> > _Mapping[] = 
    { 
     std::make_pair("pam:", boost::bind(&PamEvent)), 
     std::make_pair("none", boost::bind(&DefaultEvent)) 
    }; 
    std::cout << "sizeof _Mapping " << sizeof _Mapping << std::endl; 
    std::cout << "sizeof (std::pair<Arg, Callback>) " << sizeof (std::pair<std::string, boost::function<void(void)> >) << std::endl; 

    CallbackSelector<std::string, boost::function<void(void)> > Selector(_Mapping); 
} 

(The full executable version of this example)

std::pair<std::string, boost::function<void(void)> > _Mapping[]을 CallbackSelector 클래스 생성자로 전달하는 오류로 인해 매핑의 크기가 2가 아니기 때문에이 코드는 컴파일되지 않습니다. 출력을 보면이를 확인할 수 있습니다.

누군가가 (분명히?) 간단한 실수를 발견하면 기쁠 것입니다. 고맙습니다.

+1

크기에 관해서, 함수 매개 변수로서의 _Mapping []은 포인터 일뿐입니다. – juanchopanza

답변

2

단지 포인터가있는 배열의 크기를 결정할 방법이 없습니다. 당신은 별도의 인수로 크기를 전달할 수 중 하나

CallbackSelector(std::pair<Arg, Callback> mapping[], size_t size) : 
    Mapping(mapping, mapping + size) 

또는 템플릿 매개 변수로 추론 : C++ 11 이상에서,

template <size_t size> 
CallbackSelector(std::pair<Arg, Callback> (&mapping)[size]) : 
    Mapping(mapping, mapping + size) 

또는, 당신은 initializer_list 인수를 취할 수

CallbackSelector(std::initializer_list<std::pair<Arg, Callback>> mapping) : 
    Mapping(mapping.begin(), mapping.end()) 

// Usage example 
CallbackSelector<std::string, boost::function<void(void)> > selector { 
    {arg1, callback1}, 
    {arg2, callback2} 
}; 

(참고 : 나는 _Mapping 이름을 변경의 자유, 사용하지 않았을해야 reserved name했다).

+0

놀라운 대답을 해주셔서 감사합니다. 마지막 옵션은 gcc 4.4.7에서도 작동했습니다. 상관 없으면 코드 예제에 템플릿 정의를 추가 할 것입니다. –

+0

배열 크기를 전달할 때 템플릿 속임수를 사용했습니다. 챔피언처럼 작동합니다. –