3

我目前开始使用 boost::program_options 来解析命令行选项以及配置文件。

是否可以使用自己的模板类作为选项参数?这意味着,像

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

namespace po = boost::program_options;

template <typename T>
class MyClass
{
private:
    T*   m_data;
    size_t m_size;
public:
    MyClass( size_t size) : m_size(size) { m_data = new T[size]; }
    ~MyClass() { delete[] m_data; }
    T get( size_t i ) { return m_data[i]; }
    void set( size_t i, T value ) { m_data[i] = value; }
};

int main (int argc, const char * argv[])
{    
    po::options_description generic("General options");
    generic.add_options() ("myclass", po::value< MyClass<int>(2) >(), 
                           "Read MyClass");
    return 0;
}

试图编译这个我得到一个语义问题(没有匹配函数调用'value')。我想我需要为通用类型提供一些转换,但我没有真正的想法。

有人可以帮忙吗?谢谢

永旺512

4

2 回答 2

2

我不知道 boost::program_options 是否允许您尝试的用例,但您得到的错误是因为您试图将对象作为模板类型传递给 po::value<>。如果在编译时知道大小,则可以将大小作为模板参数传入。

template< typename T, size_t size >
class MyClass {
  T m_data[size];
public:
  // ...
};

然后像这样使用它:

po::value< MyClass<int, 2> >()

您还应该考虑使用Boost.Array而不是我猜想实现您要实现的功能。

于 2011-04-21T12:53:02.140 回答
1

我会这样写:

MyClass<int> mine(2);
generic.add_options() ("myclass", po::value(&mine), "Read MyClass");

然后需要做的就是定义一个输入流操作符,如下所示:

std::istream& operator >>(std::istream& source, MyClass& target);

然后 Boost Program Options 将在使用该选项时调用此流运算符myclass,并且您的对象将根据该运算符的实现自动填充,而不必稍后调用 Program Options 函数之一来提取值。

如果你不喜欢上面的语法,类似的东西也应该起作用:

generic.add_options() ("myclass", po::value<MyClass<int> >()->default_value(MyClass<int>(2)), "Read MyClass");

这样,您将在不允许运行时行为的模板部分之外直接使用所需的构造函数参数创建类的实例。我不喜欢这种方式,因为它很冗长,您最终需要稍后调用更多函数来转换值。

于 2011-04-21T13:16:21.553 回答