Как реализовать универсальный C ++ для настройки функции? - PullRequest
0 голосов
/ 09 июня 2018

Я создаю общую конфигурацию функций.Я планирую определить структуру объекта, как показано ниже.

#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 голосов
/ 09 июня 2018

Один из способов - использовать специализацию 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);
}

Примечание: если вы можете, я бы избегал макросов препроцессора.Как только они начинают появляться в заголовочных файлах, ваш код становится тесно связанным с глобальным пространством имен.Это делает написание тестов или повторное использование кода в других проектах более проблематичным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...