Написание конструктора класса шаблона с параметрами, зависящими от аргумента шаблона - PullRequest
0 голосов
/ 23 мая 2018

Рассмотрим следующие два класса с конструкторами, которые принимают совершенно разные наборы параметров.

class A {
public:
  A(int x, double y) {
    //do something
  }
};

class B {
public:
  B(const std::vector<bool>& x) {
    //do something
  }
};

Теперь я хочу написать шаблон класса TpC, который будет иметь объект (который может быть A или B иличто-то другое).Другими словами, я хочу использовать следующее:

int x;
double y;
std::vector<bool> z;
TpC<A> obj_a (x, y);
TpC<B> obj_b (z);

Как я могу написать конструктор для TpC, который зависит от параметров конструкторов A и B?Было бы приемлемо написать что-то вроде признака / политики, чтобы сообщить TpC, какими должны быть параметры для каждой конкретной специализации.

Ответы [ 3 ]

0 голосов
/ 23 мая 2018

Вам необходимо использовать конструктор шаблонов.Однако, чтобы не вызывать этот конструктор вместо конструктора копирования, вам нужно добавить немного устранения неоднозначности.Например:

template<class T>
class TpC {
     T t;
public:
     struct in_place_t { };
     static constexpr in_place_t in_place;
     template<class... ARGS>
     TpC(in_place_t, ARGS... args) : t(std::forward<ARGS>(args)...) {}
};

В C ++ 17 in_place доступно в std.

0 голосов
/ 23 мая 2018

Если вы используете c ++ 11 или более позднюю версию, вы можете использовать вариативный шаблонный конструктор с расширением пакета параметров, вызывающим std :: forward для аргументов конструктора.Что-то вроде:

template <typename T>
class TpC {
    T base;
public:
    template <typename... Args>
    TpC(Args&&... args)
    : base(std::forward<Args>(args)...) {
    }
};
0 голосов
/ 23 мая 2018

Вы можете написать конструктор шаблона с пакетом параметров для TpC.(Как и предполагалось в комментариях, я использовал SFINAE для ограничения шаблона, в противном случае он мог бы быть лучше, чем конструктор копирования. См. Весь фрагмент кода по ссылке, которую я разместил.)

template <typename T, typename... U>
struct my_is_same {
    constexpr static bool value = false;
};
template <typename T1, typename T2, typename... U>
struct my_is_same<T1, T2, U...> {
    constexpr static bool value = std::is_same_v<T1, std::remove_cvref_t<T2>>;
};
template <typename T, typename... U>
inline constexpr bool my_is_same_v = my_is_same<T, U...>::value;

template <typename T>
class TpC {
    T t;
public:
    template <typename... Args, typename = std::enable_if_t<
                                             !my_is_same_v<TpC, Args...> &&
                                             std::is_constructible_v<T, Args&&...>
                                           >>
    TpC(Args&& ... args) : t(std::forward<Args>(args)...) {}
};

изатем

int x;
double y;
std::vector<bool> z;
TpC<A> obj_a (x, y);
TpC<B> obj_b (z);

LIVE

...