Структура шаблона, которая может иметь или не иметь члена - PullRequest
0 голосов
/ 14 ноября 2018

Возможно ли иметь структуру, которая может иметь или не иметь члена?Примерно так:

template <typename T, typename A = some_type_with_size_0>
struct s {
    T t;
    A aux;
};

Если быть точным, если бы я попросил s<int, int>, я бы получил структуру с двумя int с, но если бы я попросил s<int>, я бы получил структуру столько int.

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

В C ++ 20 можно будет делать то, что вы пытаетесь сделать напрямую:

template <typename T, typename A = some_type_with_size_0>
struct s {
    T t;
    [[no_unique_address]] A aux;
};

См. https://en.cppreference.com/w/cpp/language/attributes/no_unique_address.

В C ++ 17 естьнет простого способа указать член, который условно исчезает.Вам необходимо написать полномасштабную частичную специализацию, например, так:

template <typename T, typename A = void>
struct s {
    T t;
    A aux;
};
template <typename T>
struct s<T, void> {
    T t;
};

К сожалению, это требует от вас повторения ввода всех общих членов (в данном случае только t).Чтобы избежать этого, мы можем вставить условно представленные члены в базовый класс:

template <typename T, typename A = void>
struct s : optional_aux<A> {
    T t;
};
template <typename A>
struct optional_aux {
    A aux;
};
template <>
struct optional_aux<void> { };

В случае, когда A = void, этот базовый класс пуст, поэтому компилятор может по своему усмотрению удалить его полностью, делаяsizeof(s<T, void>) потенциально равно sizeof(T).Атрибут [[no_unique_address]] в основном делает пустую оптимизацию базового класса доступной и для членов.

0 голосов
/ 14 ноября 2018

Вы можете использовать шаблон переменной:

template <typename...> struct Generic;

template <typename T1> struct Generic<T1> {
  T1 field1;
};

template <typename T1, typename T2> struct Generic<T1, T2> {
  T1 field1;
  T2 field2;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...