boost :: program_options似乎将std :: array强制转换为boost :: array

时间:2016-07-19 17:45:12

标签: c++ c++11 boost boost-program-options stdarray

考虑以下计划:

PY3 = sys.version_info[0] > 2


class Test:
    def __init__(self):
        self.contents = ''
        if PY3:
            self.contents = self.contents.encode('ascii')

如果用

编译
#include <iostream>
#include <sstream>
#include <array>
#include <type_traits>

#ifdef DO_BOOST_PO_TEST
#include <boost/program_options.hpp>
namespace po = boost::program_options;
#endif

template <size_t I, typename T, size_t N>
typename std::enable_if<(I==N-1)>::type
array_elem_from_istream(std::istream& in, std::array<T,N>& arr) {
  std::stringstream ss;
  in.get(*ss.rdbuf(),(char)EOF);
  ss >> std::get<I>(arr);
}

template <size_t I, typename T, size_t N>
typename std::enable_if<(I<N-1)>::type
array_elem_from_istream(std::istream& in, std::array<T,N>& arr) {
  std::stringstream ss;
  in.get(*ss.rdbuf(),':');
  ss >> std::get<I>(arr);
  in.ignore(); // skip delim char
  array_elem_from_istream<I+1>(in,arr);
}

namespace std {
  template <typename T, size_t N>
  istream& operator>>(istream& in, array<T,N>& arr) {
    array_elem_from_istream<0>(in,arr);
    return in;
  }
}

int main(int argc, char *argv[])
{
  std::array<double,3> arr;

  #ifndef DO_BOOST_PO_TEST
  std::stringstream(argv[1]) >> arr;
  #else

  try {
    po::options_description desc("Options");
    desc.add_options()
      ("arr,a", po::value(&arr), "array test");
    po::positional_options_description pos;
    pos.add("arr",1);

    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv)
      .options(desc).positional(pos).run(), vm);
    po::notify(vm);
  } catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
    return 1;
  }
  #endif

  for (auto x : arr) std::cout << x << std::endl;

  return 0;
}

g++ -std=c++11 -Wall test.cc -o test 打印

./test '1:5:9'

正如所料。但是用

进行编译
1
5
9

导致错误。错误消息中最具启发性的部分是

g++ -std=c++11 -Wall -DDO_BOOST_PO_TEST test.cc -o test -lboost_program_options

为什么世界上它应该在使用/foo/bar/include/boost/lexical_cast/detail/converter_lexical_streams.hpp:601:32: error: no match for ‘operator>>’ (operand types are ‘std::basic_istream<char>’ and ‘boost::array<double, 3ul>’) 时寻找operator>>(std::istream&, boost::array<double, 3ul>&)

如果我将operator>>(std::istream&, std::array<double, 3ul>&)array_elem_from_istream模板函数'istream& operator>>参数更改为arr,请将boost:array保留在std::array<double,3> arr;中是的,它有效!

main为什么std::array<double,3>boost::array<double,3>投放到boost::program_options?这是我第一次看到boost::program_options更改其查找流操作符的类型。

0 个答案:

没有答案