2011-04-21 100 views
3

我目前开始使用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; 
} 

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

任何人都可以帮忙吗? 感谢

Aeon512

回答

1

我会写这样的:

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

然后,所有需要做的是定义一个输入流操作是这样的:

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

然后升压程序选项将调用此流如果使用myclass选项,并且您的对象将根据该运算符的实现自动填充,而不必稍后调用某个“程序选项”函数来提取值。

如果你不喜欢上面的语法,像应太:

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

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

+0

感谢您的提示。它完美的作品。 – Aeon512 2011-04-21 14:51:40

+0

太棒了。我最后使用了哪两个想法? – 2011-04-21 22:40:56

2

我不知道的boost :: program_options让你试图用例,但你得到的错误是因为你试图传递一个对象作为模板类型po ::值<>。如果在编译时已知大小,则可以将大小作为模板参数传入。

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

,然后用它像这样:

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

你也应该考虑使用Boost.Array而不是我想满足你想实现什么。

+1

+1,用于诊断错误。 – rcollyer 2011-04-21 14:17:56

相关问题