其他类数据类型的扩展boost::lexical_cast



是否可以扩展boost::lexical_cast来处理其他数据类型,而无需实际修改这些类?

在我的例子中,我想扩展它来处理像cv::Pointcv::Point3这样的事情,获取一个以字符串分隔的坐标列表并加载它们。。因此,有能力做一些类似的事情:

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

cv::Point类已经有流运算符,但与istreamwstream不兼容,因此它失败了。

编辑

我之所以这么问,是因为我在一个带有模板函数get_parameter的框架中工作,该函数使用boost::lexical_cast将字符串(从配置文件中读取)转换为所需的数据类型。它对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

您可以为要转换的类型定义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;
    }

打印CCD_ 9。

从一个字符串到一个点需要更多的工作,但您可以看到如何做到这一点

如果内存正常,您应该能够定义lexical_cast将使用的自由函数(istream& operator>>(istream&, cv::Point&)),只要它是在lexical_cast调用之前定义的。

编辑:请参阅重载istream运算符>gt;c++,例如

编辑2:这是一个工作示例(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类成为模板类,因为它似乎是您的

编辑4:使用OpenCV 2.4.10,也适用于上述设置:

#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;
}

相关内容

  • 没有找到相关文章

最新更新