2014-10-08 4 views
0

boost::lexical_cast을 확장하여 실제로 다른 클래스를 수정하지 않고도 다른 데이터 유형을 처리 할 수 ​​있습니까? 내 경우 다른 클래스 데이터 유형에 대한 boost :: lexical_cast 확장

, 나는 ...이 cv::Pointcv::Point3, 좌표의 캐릭터로 구분 된 목록을 복용하고로드 등의 작업을 처리하기 위해 확장 할 그래서 같은 것을 할 수있는 능력 :

cv::Point mypoint = boost::lexical_cast<cv::Point>("2,4"); 

cv::Point 클래스에는 이미 스트림 연산자가 있지만 istreamwstream과 호환되지 않으므로 실패합니다. 내가 원하는 데이터 타입으로 (구성 파일에서 읽기) 문자열을 변환 할 boost::lexical_cast를 사용하는 템플릿 기능 get_parameter와 프레임 워크에서 일하고 있기 때문에

편집 나는이를 부탁드립니다. 그것은 ints & 수레에 잘 작동하지만, 지금은 2D 또는 3D 포인트 (또는 더 나쁜 계수의 배열)를 읽으려면 여러 번 호출해야합니다. 이러한 경우를 처리하기 위해 lexical_cast를 수정할 수 있으면 좋을 것입니다.

이와 같이 이것은 OpenCV에만 해당되는 것이 아니며 가장 간단한 데이터 유형으로 선택했습니다. 저는 일반적인 솔루션에 더 관심이 있습니다. 여기에 편집 2

내가하려고했는데 샘플 응용 프로그램입니다 :

#include <opencv2/opencv.hpp> 
#include <boost/lexical_cast.hpp> 

template <typename T> 
std::istream& operator>>(std::istream& stream, cv::Point_<T> &p) { 
    // Eventually something will go here 
    // to put stream into p 
} 

int main(int argc, char **argv) { 
    cv::Point_<float> p = boost::lexical_cast<cv::Point_<float>>(std::string("1,2")); 
    std::cout << "p = " << p << std::endl; 
    return 0; 
} 

을 그리고 그렇게 같은 아름다운 C++ 템플릿 오류와 함께 실패 :

In file included from /home/rhand/Development/mlx/ml_3rdparty/install/boost/include/boost/lexical_cast.hpp:41:0, 
      from /home/rhand/Development/experiments/lexical_Cast/test.cc:2: 
/home/rhand/Development/mlx/ml_3rdparty/install/boost/include/boost/lexical_cast.hpp: In instantiation of ‘struct boost::detail::deduce_target_char_impl<boost::detail::deduce_character_type_later<cv::Point_<float> > >’: 
/home/rhand/Development/mlx/ml_3rdparty/install/boost/include/boost/lexical_cast.hpp:415:89: required from ‘struct boost::detail::deduce_target_char<cv::Point_<float> >’ 
/home/rhand/Development/mlx/ml_3rdparty/install/boost/include/boost/lexical_cast.hpp:674:92: required from ‘struct boost::detail::lexical_cast_stream_traits<std::basic_string<char>, cv::Point_<float> >’ 
/home/rhand/Development/mlx/ml_3rdparty/install/boost/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 = cv::Point_<float>; Source = std::basic_string<char>]’ 
/home/rhand/Development/mlx/ml_3rdparty/install/boost/include/boost/lexical_cast.hpp:2543:50: required from ‘Target boost::lexical_cast(const Source&) [with Target = cv::Point_<float>; Source = std::basic_string<char>]’ 
/home/rhand/Development/experiments/lexical_Cast/test.cc:11:82: required from here 
/home/rhand/Development/mlx/ml_3rdparty/install/boost/include/boost/static_assert.hpp:31:45: error: static assertion failed: Target type is neither std::istream`able nor std::wistream`able 
#  define BOOST_STATIC_ASSERT_MSG(...) static_assert(__VA_ARGS__) 
             ^
/home/rhand/Development/mlx/ml_3rdparty/install/boost/include/boost/lexical_cast.hpp:388:13: note: in expansion of macro ‘BOOST_STATIC_ASSERT_MSG’ 
     BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_right_shift<std::basic_istream<wchar_t>, T >::value), 
     ^
make[2]: *** [CMakeFiles/test.dir/test.cc.o] Error 1 
make[1]: *** [CMakeFiles/test.dir/all] Error 2 
make: *** [all] Error 2 
+1

'lexical_cast'전문화를 제공 할 수 없습니까? – Chad

+0

왜 그냥 무료 함수를 만드는 대신 lexical_cast에서 비헤이비어를 강요하는 것이 더 좋습니까? 나는 단지 궁금하다. –

+0

내가 작업하고있는 프레임 워크는 boost :: lexical_cast를 내부적으로 사용하여 (파일에서 읽기) 원하는 데이터 유형으로 문자열을 변환하는 템플릿 함수'get_parameter'를 가지고 있습니다. 지금은 수동으로 X & Y를 별도로 읽어야합니다. 단순히 cv :: Point를 읽는 것이 편리 할 것입니다. – Yeraze

답변

1
: OpenCV의 2.4.10로, 또한 상기 설정에서 작동

변환하려는 유형에 대해 boost :: lexical_cast의 특수화를 정의 할 수 있습니다.

장난감 예 :

typedef struct { int x; int y; } Point; 

namespace boost { 
    template<> 
     std::string lexical_cast(const Point& arg) { return "2,3"; } 
} 

int main() { 
    std::cout << boost::lexical_cast<std::string>(Point()) << std::endl; 
    } 

인쇄 2,3.

문자열에서 포인트로 이동하려면 좀 더 많은 작업이 필요하지만 어떻게해야하는지 알 수 있습니다.

+0

그거야! 감사! – Yeraze

1

하는 경우 메모리가 올바르게 작동한다면, 정의 된 한 lexical_cast이 사용하게 될 자유 함수 (istream& operator>>(istream&, cv::Point&))를 정의 할 수 있어야합니다 lexical_cast 호출 전에 d.

편집 : 예

편집 2 Overloading istream operator>> c++를 참조하십시오 여기에 작업 예제 (VS2013는 1.44 부스트 [그래, 내가 업데이트해야합니다!). 당신의 경우에 실패한 최소한의 예를 게시 할 수 있습니까?

#include <iostream> 
#include <boost/lexical_cast.hpp> 

template <typename ElementType> 
struct Point 
{ 
    Point() : x(0), y(0) {} 
    ElementType x, y; 
}; 

template <typename ElementType> 
std::istream& operator>>(std::istream& stream, Point<ElementType> &p) 
{ 
    stream >> p.x; 
    stream.get(); 
    stream >> p.y; 
    return stream; 
} 

template <typename ElementType> 
std::ostream& operator<<(std::ostream& stream, const Point<ElementType> &p) 
{ 
    stream << p.x << "," << p.y; 
    return stream; 
} 

int main(int argc, char **argv) 
{ 
    Point<int> p = boost::lexical_cast<Point<int>>("1,2"); 
    std::cout << "p=[" << p << "]"; 
    std::cin.get(); 
    return 0; 
} 

편집 3 : 그것은 당신의 경우 것으로 보인다 이후의 Point 클래스 A 템플릿을 만들어 편집 4

:

#include <iostream> 
#include <boost/lexical_cast.hpp> 
#include <opencv2/opencv.hpp> 

template <typename ElementType> 
std::istream& operator>>(std::istream& stream, cv::Point_<ElementType> &p) 
{ 
    stream >> p.x; 
    stream.get(); 
    stream >> p.y; 
    return stream; 
} 

int main(int argc, char **argv) 
{ 
    auto cv_p = boost::lexical_cast<cv::Point_<float>>(std::string("1,2")); 
    std::cout << "opencv p=" << cv_p << ""; 
    std::cin.get(); 
    return 0; 
} 
+0

hrm .. 작동하지 않는 것 같습니다, 템플릿을 추가했습니다. cv :: Point_ & operator << (std :: istream & is, std :: string & is) "및 스텁"템플릿 std :: istream & operator >> (std :: istream & is, cv :: Point_ & p) "그리고 여전히 istream 및 wstream과 호환되지 않는다고 불평합니다. – Yeraze

+0

@Yeraze 헴, 죄송합니다. 그때 옳은 길을 기억하지 못합니다 ... 그 때까지 솔루션이 게시되지 않으면 집에 갈 때 검색하겠습니다. –

+0

@Yeraze OpenCV의 Point를 사용하지는 않았지만 최소한의 예제를 추가했습니다. 이 간단한 케이스가 툴툴에서 작동하는지 확인해 주시겠습니까? –