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

C++ 如何实现通用c++;用于配置功能?,c++,templates,generic-programming,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::

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

#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);

谢谢

一种方法是使用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);
}
#包括
#包括
#包括
//某些类型列表是否包含类型Seek?
样板
结构元组包含;
//专门处理空列表(错误)
模板结构元组包含:std::false\u类型{};
//专门针对第一种类型==搜索
样板
结构元组包含:std::true\u类型{};
//所有其他案例的优先级较低(不太专业)
样板
结构元组包含:元组包含{};
//元组的特殊情况。这应该有一个不同的名称。
样板
结构元组包含:元组包含{};
//一些选择
结构CoolOption1{};
结构CoolOption2{};
结构CoolOption3{};
//我们当前的选项集
使用CurrentOptions=std::tuple;
//测验
int main()
{
constexpr bool hasopt1=元组包含();
constexpr bool hasopt2=元组包含();
constexpr bool hasopt3=元组包含();
静态断言(hasopt1==true);
静态断言(hasopt2==false);
静态断言(hasopt3==true);
}

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

这看起来像是XY问题。如果是c++11或更高版本,建议使用包含位的constexpr int。容易多了。