2014-10-09 1 views
1

Я пытаюсь расширить lexical_cast обрабатывать string-> резюме :: преобразование Point, с кодом, как так:Перегрузка lexical_cast с шаблонным классом

#include <iostream> 
#include <opencv2/opencv.hpp> 
#include <boost/lexical_cast.hpp> 
#include <boost/algorithm/string/classification.hpp> 
#include <boost/algorithm/string/split.hpp> 

namespace boost { 
    template<> 
    cv::Point2f lexical_cast(const std::string &str) { 
     std::vector<std::string> parts; 
     boost::split(parts, str, boost::is_any_of(",")); 
     cv::Point2f R; 
     R.x = boost::lexical_cast<float>(parts[0]); 
     R.y = boost::lexical_cast<float>(parts[1]); 
     return R; 
    } 
} 

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

И это прекрасно работает .. Однако, cv::Point2f на самом деле cv::Point_<T> где T может быть int, float, double и т. Д. Я все равно не могу найти, что templated arg для lexical_cast, так что у меня может быть одна функция lexical_cast, которая может обрабатывать все типы cv::Point_<T>.

ответ

1
template <typename T> 
struct point_type {}; 

template <typename T> 
struct point_type<cv::Point_<T>> { using type = T; }; 

namespace boost { 
    template <typename T, typename U = typename point_type<T>::type> 
    T lexical_cast(const std::string &str) 
    { 
     std::vector<std::string> parts; 
     boost::split(parts, str, boost::is_any_of(",")); 
     T R; 
     R.x = boost::lexical_cast<U>(parts[0]); 
     R.y = boost::lexical_cast<U>(parts[1]); 
     return R; 
    } 
} 

DEMO


предыдущий, немного более сложное решение, если вам не нравится этот неявный второй параметр шаблона lexical_cast:

#include <type_traits> 

template <typename T> 
struct is_point : std::false_type {}; 

template <typename T> 
struct is_point<cv::Point_<T>> : std::true_type {}; 

template <typename T> 
struct point_type; 

template <typename T> 
struct point_type<cv::Point_<T>> { using type = T; }; 

namespace boost { 
    template <typename T> 
    auto lexical_cast(const std::string &str) 
     -> typename std::enable_if<is_point<T>::value, T>::type 
    { 
     std::vector<std::string> parts; 
     boost::split(parts, str, boost::is_any_of(",")); 
     using U = typename point_type<T>::type; 
     T R; 
     R.x = boost::lexical_cast<U>(parts[0]); 
     R.y = boost::lexical_cast<U>(parts[1]); 
     return R; 
    } 
} 

DEMO 2

+0

Это работает! Хотя, я не уверен, что именно происходит там ... – Yeraze

+0

@Yeraze магия специализаций шаблонов и SFINAE –

+0

@Yeraze Я немного упростил его –

 Смежные вопросы

  • Нет связанных вопросов^_^