我想有一个程序来解析和管理命令行参数。正如您在this
- 函数中所看到的,通过使用main
之类的简单命令,您可以指定选项值应具有的类型(在本例中为Option<int>("number", { "-n", "--number" })
),每个选项的唯一标识符(如int
),以及可以引入此选项的多个字符串。此外,许多选项应包含在名为"number"
的类中,这样可以简化对其选项的访问。
但在我的实际代码中,我现在遇到了几个问题:
OptionSet
内存储一个具有不同模板参数的类的多个实例。例如,在我的代码中,std::vector
应存储在Option<int>
和Option<std::string>
等相同的向量中。
也许甚至可以将模板参数分别存储在另一个向量中?Option<double>
,using
和std::enable_if_t
我创建了一个名为std::is_same
的类型。如果模板参数OptionHasValue
为false且Invert
为T
,则void
的类型无效,否则它具有模板参数OptionHasValue
指定的类型。 U
使用OptionValue
和一些SFINAE魔法来决定它是否应该具有支持值存储所需的方法。也就是说,OptionHasValue
的第一个版本具有OptionValue
作为其第二个模板参数,因此如果OptionHasValue<T>
为T
,它将变为无效(并由编译器删除)。另一个版本的void
具有相反的行为,因为其第二个模板参数为OptionValue
而OptionHasValue<T, true>
反转了true
的行为。OptionHasValue
本身继承自Option
,因此如果您创建类似OptionValue
的选项,则它不支持值(即,它缺少Option<void>
之类的函数,应该setValue
和setValueFromString
。另一方面,如果您创建类似getValue
的选项,则生成的类实例具有所有这些功能
现在的问题是,(例如)Option<int>
访问OptionSet::process()
和Option::hasValue
,但后者仅在Option::setValueFromString
为真时声明(以及相应的模板参数该选项不是Option::hasValue
)。但由于void
未包含在某种模板中,编译器也会抱怨。Option::setValueFromString
- 函数中,我使用函数main
。此函数应返回选项的值(在调用optionSet.getOptionValue(std::string)
后设置之后)。现在最困难的是返回类型取决于process()
的返回值,该函数循环遍历所有可用选项并返回带有所需标识符的选项。findOptionByIdentifier
为identifier
(如本问题开头的"number"
示例所示),则Option
的返回类型为{{1}因为唯一具有标识符findOptionByIdentifier
的选项是Option<int>
作为其第一个模板参数的选项,最终会导致"number"
具有返回类型int
。getOptionValue
- 函数的最后几行中查看注释中的预期行为。那么,我需要在以下代码中修改以修复所有这些内容(并使其编译)?我使用的是g ++ 5.2.0(mingw-w64),所以我可以使用C ++ 11和C ++ 14的任何功能。
int
答案 0 :(得分:0)
我不确定我是否完全理解这个问题,但我会尽力回答。
我想存储一个具有不同类的多个实例 模板参数
没有这样的事情。具有不同模板参数的模板是不同的类。但是,您似乎通过boost::any
成功解决了这个问题。您还可以使用其他类型删除技术 - 例如,为您的所有选项设置非模板父级,或切换到非类型删除boost::variant
,因为您似乎只有有限数量的可能选项类型。
通过使用using,std :: enable_if_t和std :: is_same我创建了一个类型 叫做OptionHasValue ......
首先,我不会在这个例子中使用SFINAE。简单的部分专业化就足够了。至于opt.setValueFromString(argvVec[i]);
,只需在void选项类中创建一个NOOP函数。
关于最后一个问题,只需使用模板化函数接收对返回类型的引用,而不是返回它。