如何实现通用c ++配置功能?

时间:2018-06-09 06:31:50

标签: c++ templates generic-programming

我正在构建通用功能配置。我正在计划如下定义特征结构。

#define DEFINE_FEATURE(NAME) struct Feature##NAME {};

我可以将它们定义为:

DEFINE_FEATURE(A)
DEFINE_FEATURE(B)
DEFINE_FEATURE(C)

如何实现可用于定义各种功能组合的泛型类?它拥有所有功能。

#define DEFINE_CONFIG(NAME, FeatureA,...) \ 
auto config_##NAME = Config::create().set_feature(FeatureA{}).set_feature(FeatureB).set_feature(....)()

例如,我将新/旧产品配置定义为

DEFINE_CONFIG(NewProduct, FeatureA, FeatureB, FeatureC);
DEFINE_CONFIG(OldProduct, FeatureA);

谢谢!

1 个答案:

答案 0 :(得分:1)

一种方法是使用std :: tuple特化作为选项集合。

#include <memory>
#include <tuple>
#include <type_traits>


// does some list of type contain type Seek?
template<class Seek, class...Ts>
struct tuple_contains;

// specialise for empty list (false)
template<class Seek> struct tuple_contains<Seek> : std::false_type {};

// specialise for first type == Seek    
template<class Seek, class...Rest>
struct tuple_contains<Seek, Seek, Rest...> : std::true_type {};

// lower priority for all other cases (less specialised)
template<class Seek, class This, class...Rest>
struct tuple_contains<Seek, This, Rest...> : tuple_contains<Seek, Rest...> {};

// special case for tuple. This should probably have a different name.    
template<class Seek, class...Ts>
struct tuple_contains<Seek, std::tuple<Ts...>> : tuple_contains<Seek, Ts...> {};

// some options
struct CoolOption1 {};
struct CoolOption2 {};
struct CoolOption3 {};

// our current option set    
using CurrentOptions = std::tuple<CoolOption1, CoolOption3>;

// tests
int main()
{
    constexpr bool hasopt1 = tuple_contains<CoolOption1, CurrentOptions>();
    constexpr bool hasopt2 = tuple_contains<CoolOption2, CurrentOptions>();
    constexpr bool hasopt3 = tuple_contains<CoolOption3, CurrentOptions>();

    static_assert(hasopt1 == true);
    static_assert(hasopt2 == false);
    static_assert(hasopt3 == true);
}

注意:如果可以的话,我会避免使用预处理器宏。一旦它们开始出现在头文件中,您的代码就会紧密耦合到全局命名空间。这使得在其他项目中编写测试或重用代码更加成问题。