Я пытаюсь расширить lexical_cast для обработки преобразований string-> cv :: Point с помощью следующего кода:
#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 и т. д. Я не могу найти, чтобы выставить этот шаблонный аргумент в lexical_cast, чтобы у меня была одна функция lexical_cast, которая может обрабатывать все cv::Point_<T>
типы.
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;
}
}
Предыдущее, немного более сложное решение, если вам не нравится этот неявный второй параметр шаблона 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;
}
}