重载的验证不明确

重载的验证不明确

我试图解析从命令行输入的列表。

我的课是从向量派生的

编译器抱怨重载的验证不明确。
我知道为什么,但是不知道如何解决这个问题。

请帮忙。

以下是产生错误的最小示例。如果将ch_list的类型更改为向量,则将编译此最小示例。

// g++ -std=c++11 -Wall -Wextra -pedantic test.cpp -o test -lboost_program_options -lboost_system

#include <vector>
#include <boost/program_options.hpp>
#include <iostream>
#include <vector>

using namespace std;

class mylist : public vector<int> {
public:
    friend istream &operator>>(istream &is, mylist& l) {
        int val;
        is >> val;
        l.push_back(val);
        return is;
    }
    friend ostream& operator<<(ostream& os, const mylist& l) {
        return os << l[0];
    }
};

int main (int argc, char* argv[])
{
    //vector<int> ch_list; // This works
    mylist ch_list; // This doesn't

    namespace po = boost::program_options;
    po::options_description desc("Allowed options");
    desc.add_options()
        ("ch", po::value<decltype(ch_list)>(&ch_list), "Set channel numbers")
    ;

    po::variables_map vm;
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
    }
    catch (po::error& e) {
        cerr << "ERROR: " << e.what() << "\n";
        return EXIT_FAILURE;
    }
    if (!ch_list.empty())
        cout << ch_list[0] << "\n";

    return EXIT_SUCCESS;
}


我得到这些错误

/usr/include/boost/program_options/detail/value_semantic.hpp: In instantiation of ‘void boost::program_options::typed_value<T, charT>::xparse(boost::any&, const std::vector<std::basic_string<charT> >&) const [with T = mylist; charT = char]’:
test.cpp:47:5:   required from here
/usr/include/boost/program_options/detail/value_semantic.hpp:169:13: error: call of overloaded ‘validate(boost::any&, const std::vector<std::basic_string<char> >&, mylist*, int)’ is ambiguous
/usr/include/boost/program_options/detail/value_semantic.hpp:169:13: note: candidates are:
/usr/include/boost/program_options/detail/value_semantic.hpp:81:10: note: void boost::program_options::validate(boost::any&, const std::vector<std::basic_string<charT> >&, T*, long int) [with T = mylist; charT = char]
/usr/include/boost/program_options/detail/value_semantic.hpp:129:10: note: void boost::program_options::validate(boost::any&, const std::vector<std::basic_string<charT> >&, std::vector<_RealType>*, int) [with T = int; charT = char]

最佳答案

您可以使用custom validator。您的代码为:

#include <vector>
#include <boost/program_options.hpp>
#include <iostream>
#include <vector>

using namespace std;
namespace po = boost::program_options;

class mylist : public vector<int> {
public:
};

void validate(boost::any& v,
  const vector<string>& values,
  mylist*, int) {
  mylist dvalues;
  for(vector<string>::const_iterator it = values.begin();
    it != values.end();
    ++it) {
    stringstream ss(*it);
    copy(istream_iterator<int>(ss), istream_iterator<int>(),
      back_inserter(dvalues));
    if(!ss.eof()) {
      throw ("Invalid coordinate specification");
    }
  }
  v = mylist(dvalues);
}

int main (int argc, char* argv[])
{
    //vector<int> ch_list; // This works
    mylist ch_list; // This doesn't

    po::options_description desc("Allowed options");
    desc.add_options()
        ("ch", po::value< mylist  >(&ch_list)->multitoken(), "Set channel numbers")
    ;

    po::variables_map vm;
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
    }
    catch (po::error& e) {
        cerr << "ERROR: " << e.what() << "\n";
        return EXIT_FAILURE;
    }

    for (auto cc : ch_list)
      cout << cc << endl;

    return EXIT_SUCCESS;
}


参考:boost::program_options config file option with multiple tokens

09-06 13:24