2014-11-21 6 views
2

정수 옵션에 대한 특수 처리를 원합니다. 설명서에 따르면 필자는 자체 유효성 검사 함수를 작성해야합니다. 다음의 짧은 프로그램을 생각해보십시오.boost program_options에 대한 사용자 정의 유효성 검사기가 GCC와 작동하지 않습니다. MSVC와 함께 작동합니다.

#include <iostream> 
#include <vector> 
#include <string> 

#include <boost/program_options.hpp> 

namespace po = boost::program_options; 

namespace boost { namespace program_options { 
template <class charT> 
void validate(boost::any& v, const std::vector<std::basic_string<charT> >& xs, unsigned int*, int) 
{ 
    std::cout << "validate is redefined" << std::endl; 
    // do something else 
} 
}} 

int main(int argc, char* argv[]) 
{ 
    po::options_description cmdLineOptions; 
    po::variables_map vm; 

    unsigned int v; 
    const char* args[] = {"tst", "-k", "10"}; 

    cmdLineOptions.add_options() 
     ("key,k", po::value<unsigned int>(&v)->required()) 
     ; 

    po::store(po::command_line_parser(sizeof(args)/sizeof(args[0]), args).options(cmdLineOptions).run(), vm); 
    po::notify(vm); 

    std::cout << v << '\n'; 

    return 0; 
} 

그것은 완벽 VS 2013 년 작품과 출력 GCC에서

validate is redefined 
10 

는 결코 유효성 검사 함수 내에서 단계를하지 않습니다.

증명 : http://coliru.stacked-crooked.com/a/fd558ebf987a4bbe

내가 대신 서명되지 않은 INT의 사용자 지정 형식을 사용하려고하면, GCC 어쨌든 program_option에서 유효성 검사를 사용하려고 할 오류의 무리와 함께 종료됩니다.

내가 뭘 잘못하고 있니?

답변

1

예비 직감에 바로 내장의 유형에 동작을 사용자 정의 그것은 나쁜 생각입니다

BOOST_STRONG_TYPEDEF(unsigned int, Unsigned); 

을 사용하는 것이 좋습니다.


해결책 : 부분 순서 지정과 관련이 있습니다.

boost::program_options 네임 스페이스 외부로 오버로드를 이동하면 더 이상 기본 템플릿과 경쟁하지 않으므로 작동을 시작합니다.

Live On Coliru

#include <iostream> 
#include <vector> 
#include <string> 

#include <boost/any.hpp> 
#include <boost/serialization/strong_typedef.hpp> 
#include <boost/program_options.hpp> 

BOOST_STRONG_TYPEDEF(unsigned, Unsigned) 

template<class charT> 
    void validate(boost::any& v, 
      const std::vector< std::basic_string<charT> >& xs, 
      Unsigned* p, int) 
    { 
     std::cout << "validate is redefined" << std::endl; 
     // do something else 
    } 

namespace po = boost::program_options; 

int main() 
{ 
    po::options_description cmdLineOptions; 
    po::variables_map vm; 

    Unsigned v; 
    const char* args[] = {"tst", "-k", "10"}; 

    cmdLineOptions.add_options() 
     ("key,k", po::value<Unsigned>(&v)->required()) 
     ; 

    po::store(po::command_line_parser(sizeof(args)/sizeof(args[0]), args).options(cmdLineOptions).run(), vm); 
    po::notify(vm); 

    std::cout << v << '\n'; 

    return 0; 
} 

원인은 MSVC의 유명 나누어 2 상 룩업 ​​가능성

+0

토륨 해결 방법이 있습니다. 예, GCC 부분 정렬이 깨진 것 같습니다. – noxmetus

+0

@noxmetus 아직 확신하지 못했습니다. Clang도 마찬가지입니다. 아마도 좀 더 나은 것으로 문서화 될 수있는 무언가 일 것입니다 ... – sehe

+0

대개 해결 방법은 유용하지 않습니다. 대개 유효성 검사기 내부에서 check_first_occurrence 및 get_single_string을 호출하고 program_options 헤더 파일 내에서 정의되기 때문입니다. – noxmetus