I'm trying to extend lexical_cast to handle string->cv::Point conversions, with code like so:
#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;
}
And it works great.. However, cv::Point2f
is actually cv::Point_<T>
where T can be int, float, double, etc. I can't find anyway to expose that templated arg to the lexical_cast, so that I can have a single lexical_cast function that can handle all cv::Point_<T>
types.
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;
}
}
The previous, a little more complicated solution, if you don't like this implicit second template parameter of 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;
}
}