可以使用boost :: program_options和自己的模板类吗?

时间:2011-04-21 10:05:02

标签: class templates boost boost-program-options

我现在开始使用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')。我想我需要为一般化类型提供一些演员,但我没有真正的想法。

有人可以帮忙吗? 感谢

Aeon512

2 个答案:

答案 0 :(得分:2)

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

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

然后像这样使用它:

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

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

答案 1 :(得分:1)

我会这样写:

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

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

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

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

如果你不喜欢上面的语法,那么它也应该有用:

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

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