Условно определить переменную-член в зависимости от существования типа, из которого она сделана - PullRequest
0 голосов
/ 29 марта 2019

Предположим, у меня есть структура для данных:

struct TestData {
}

и класс с переменной-членом:

class TestContainer {
private:
  TestData data;
};

Оба определены в файле cpp из макроса, который используется в нескольких тестовых файлах.

Теперь я хочу удалить элемент данных во время компиляции, если не определена структура TestData. Если тесту не нужны данные, тогда нет необходимости определять элемент данных (и это приведет к предупреждению о том, что он не используется). Я думал об использовании std::enable_if, но не смог придумать условие. Другой подход заключается в определении базового класса шаблона и специализаций, как показано в этом вопросе , но как специализироваться на существовании типа?

Как это можно сделать?

1 Ответ

1 голос
/ 29 марта 2019

Вы можете проверить, существует ли структура или нет, если вы считаете, что предварительное объявление не существует.

В этом примере предполагается, что либо TestData всегда определено, либо никогда не определено:

#include <type_traits>

// Comment this line to trigger the static assert
struct TestData {};

template<typename, typename = void>
struct MaybeData {};

template<typename T>
struct MaybeData<T, std::void_t<decltype(sizeof(T))>> {
    T data;
};

struct TestContainer : MaybeData<struct TestData> {};

Мы можем протестировать наше решение следующим образом:

template<typename, typename = void>
constexpr auto has_data = false;

template<typename T>
constexpr auto has_data<T, std::void_t<decltype(T::data)>> = true;

static_assert(has_data<TestContainer>);

Механизм, стоящий за этим, заключается в том, что вместо отправки самой структуры (TestData) в качестве типа, мы используем struct TestData в качестве аргумента, который ссылается на тип, если он существует, но в дальнейшем объявляем его, если нет.

Затем мы используем sfinae, чтобы проверить, является ли sizeof(T) допустимым выражением. Если TestData является неполным типом, выражение недопустимо.

Однако, если полнота типа изменяется между экземплярами шаблона, программа плохо сформирована.

Живой пример

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