политика шаблонов c++ с аргументами


Я новичок в этом. Я создаю класс с политиками, которые говорят:

template <typename T,
          typename P1 = Policy1<T>,
          typename P2 = Policy2<T> >

{
    ...
}

Проблема у меня в том, что некоторые политики имеют Аргументы, и когда они находятся во время компиляции, это нормально

template <typename T,
          typename P1 = Policy1<T, size_t N>,
          typename P2 = Policy2<T> >

Но когда они находятся во время выполнения, я не уверен, что это лучший способ предоставить объект класса policy ... или это уже не политический шаблон?

2 4

2 ответа:

У вас может быть фабрика для политики:) EDIT смотрите добавлено ниже

Ooor вы можете сделать так, как это делает стандартная библиотека:

#include <string>

struct DummyPolicy { };

template <typename>
struct Policy1 { Policy1(int, std::string) { } };

template <typename T,
          typename P1 = Policy1<T> >
struct X 
{
     X(P1 p1 = {}) : _policy1(std::move(p1)) { }

   private:
     P1 _policy1;
};

И использовать его

int main()
{
     X<int, DummyPolicy> no_questions_asked;
     X<int> use_params({42, "hello world"});
}

С помощью C++03 или явных конструкторов, очевидно, сформулируйте это:

     X<int> use_params(Policy1<int>(42, "hello world"));

Смотрите жить на Колиру


Обновление: Фабрики

Вот обновление, показывающее фабричный подход:

#include <string>

namespace details
{
    template <typename PolicyImpl>
        struct PolicyFactory
        {
            static PolicyImpl Create() {
                return {};
            }
        };
}

template <typename>
struct Policy2 { Policy2(double) { } };

template <typename T,
          typename P1 = Policy2<T> >
struct X 
{
    X()      : _policy1(details::PolicyFactory<P1>::Create()) {}
    X(P1 p1) : _policy1(std::move(p1)) { }

  private:
    P1 _policy1;
};

///// supply a factor, possibly local to a TU:

namespace details
{
    template <typename T>
        struct PolicyFactory<Policy2<T> > {
            static Policy2<T> Create() { 
                return Policy2<T>(3.14);
            }
        };
}

int main()
{
     // with a factory:
     X<std::string, Policy2<std::string> > no_params_because_of_factory;
}

Смотрите жить на Колиру*

Примечание это

  • я предпочитаю конструктор pass-in подход
  • фабрика технически является чертой классом

Политики в шаблонах предназначены для настройки класса во время компиляции, а не во время выполнения (политики формируют тип экземпляра, и вы не можете определить типы во время выполнения в C++).

Параллель во время выполнения обычно называется "инъекцией зависимостей", и вы делаете это, например, передавая уже построенные объекты, которым экземпляр делегирует операции.