2015-01-08 7 views
1

STL 클래스가있는 boost::program_options::value 함수의 이상한 동작을 관찰하고 있습니다.종종 쌍으로 프로그램에 인수를 제공해야합니다 (예 : 파일 이름에 짧은 레이블이 있지만 boost::program_options::value 함수는 std::pair과 작동하지 않는 것으로 보입니다. 반면 자신이 정의한 클래스는 작동합니다. 다음 코드를 고려하십시오.부스트 프로그램 옵션 쌍 값

#include <string> 
#include <utility> 

#include <boost/program_options.hpp> 

using namespace std; 
namespace po = boost::program_options; 

class sspair: public pair<string,string> { }; 

typedef pair<string,string> mypair; 
// typedef sspair mypair; 

istream& operator>>(istream& in, mypair& ss) { 
    string s; 
    in >> s; 
    const size_t sep = s.find(':'); 
    if (sep==string::npos) { 
    ss.first = string(); 
    ss.second = s; 
    } else { 
    ss.first = s.substr(0,sep); 
    ss.second = s.substr(sep+1); 
    } 
    return in; 
} 

int main(int argc, char **argv) 
{ 
    mypair a; 

    try { 
    po::options_description all_opt("Options"); 
    all_opt.add_options() 
     ("arg,a", po::value<mypair>(&a),"colon separated pair") 
    ; 

    po::variables_map vm; 
    po::store(po::parse_command_line(argc, argv, all_opt), vm); 
    po::notify(vm); 
    } catch(exception& e) { 
    cerr << e.what() << endl; 
    exit(1); 
    } 

    cout << "a = (" << a.first << ", " << a.second << ")" << endl; 

    return 0; 
} 

typedef sspair mypair으로 예상되는 동작을 얻습니다.

$ ./test 
a = (,) 
$ ./test -a b:c 
a = (b, c) 
$ ./test -a bc 
a = (, bc) 

하지만 typedef pair<string,string> mypair와 나는 다음과 같은 컴파일 오류를 얻을 :

In file included from /usr/include/boost/any.hpp:27:0, 
       from /usr/include/boost/program_options/value_semantic.hpp:12, 
       from /usr/include/boost/program_options/options_description.hpp:13, 
       from /usr/include/boost/program_options.hpp:15, 
       from test.cc:4: 
/usr/include/boost/lexical_cast.hpp: In instantiation of ‘struct boost::detail::deduce_target_char_impl<boost::detail::deduce_character_type_later<std::pair<std::basic_string<char>, std::basic_string<char> > > >’: 
/usr/include/boost/lexical_cast.hpp:415:89: required from ‘struct boost::detail::deduce_target_char<std::pair<std::basic_string<char>, std::basic_string<char> > >’ 
/usr/include/boost/lexical_cast.hpp:674:92: required from ‘struct boost::detail::lexical_cast_stream_traits<std::basic_string<char>, std::pair<std::basic_string<char>, std::basic_string<char> > >’ 
/usr/include/boost/lexical_cast.hpp:2363:19: required from ‘static Target boost::detail::lexical_cast_do_cast<Target, Source>::lexical_cast_impl(const Source&) [with Target = std::pair<std::basic_string<char>, std::basic_string<char> >; Source = std::basic_string<char>]’ 
/usr/include/boost/lexical_cast.hpp:2543:50: required from ‘Target boost::lexical_cast(const Source&) [with Target = std::pair<std::basic_string<char>, std::basic_string<char> >; Source = std::basic_string<char>]’ 
/usr/include/boost/program_options/detail/value_semantic.hpp:89:38: required from ‘void boost::program_options::validate(boost::any&, const std::vector<std::basic_string<charT> >&, T*, long int) [with T = std::pair<std::basic_string<char>, std::basic_string<char> >; charT = char]’ 
/usr/include/boost/program_options/detail/value_semantic.hpp:170:55: required from ‘void boost::program_options::typed_value<T, charT>::xparse(boost::any&, const std::vector<std::basic_string<charT> >&) const [with T = std::pair<std::basic_string<char>, std::basic_string<char> >; charT = char]’ 
test.cc:49:1: required from here 
/usr/include/boost/lexical_cast.hpp:388:13: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>’ 
      BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_right_shift<std::basic_istream<wchar_t>, T >::value), 
      ^
make: *** [test] Error 1 

은 내가 std::array 또는 std::tuple 같은 다른 STL 컨테이너를 사용하려고하면 유사한 문제가 발생 것을 발견했다.

문제가 무엇인지 아는 사람이 있습니까?

편집 :이 문제를 일으키는 내가이 post을 읽은 후

좋아, 난 그냥, 발견. 명백하게, 스트림 연산자는 po :: value 함수의 템플릿 인수 인 클래스가 정의 된 네임 스페이스에서만 검색됩니다. 그래서 편집과 함께

namespace std { 
    istream& operator>>(istream& in, mypair& ss) { ... } 
} 

pair<string,string> 클래스가 직접 작동합니다.

이제는 std 네임 스페이스에서 연산자를 정의 할 때 어떤 단점이 있습니까? 나는 그것이 표준 보완 자체가 아니라는 것을 들었습니다.

답변

1

죄송합니다. 빠른 답변을 드릴 시간이 있습니다. 당신이 당신의 쌍으로 std::pair<std::string, std:string> 사용하려면

, 당신은 그것을 위해 operator>>(...)를 작성해야하며,이 연산자는 또한, namespace std에있을 그래서 ADL 일을해야합니다.