Задать вопрос
Lite_stream
@Lite_stream

Можно ли объявить переменную-член класса с помощью метапрограммирования?

Пример кода:

template <typename T, bool someCondition>
class Example
{

//    #ifdef SOME_CONDITION
//    int x;  
//    #endif

    // ↓ ↓ ↓  Ниже представлен псевдокод-эквивалент закомментированому коду выше: ↓ ↓ ↓ 
    if constexpr (someCondition)
    {
        int x;  
    }
    
  /* Some code... */

};

Есть ли эквивалент тому участку кода, который закомментирован (с использованием макроса), но с помощью метапрограммирования?
  • Вопрос задан
  • 126 просмотров
Подписаться 1 Простой 2 комментария
Решения вопроса 3
0hquazEd
@0hquazEd
template <bool X>
struct test
{};

template <>
struct test<true>
{
	int a;
};
Ответ написан
@res2001
Developer, ex-admin
Условия можно проверять с помощью enable_if.
Переменную, видимо, придется запихнуть во вложенную шаблонную структуру, где и использовать enable_if.
Я сам не силен в метапрограммировании, но можете начать по этой ссылке копать, там и примеров много.
Ответ написан
Комментировать
@MarkusD Куратор тега C++
все время мелю чепуху :)
Соберем немного конкретики из комментариев.

Отсюда:
Только хотелось бы без специализации, чтобы код не дублировать

Единственным дублированием кода тут будет только заголовок частичной специализации шаблона. В силах писателя определить общий между специализациями код и вынести его в родительский для всех специализаций класс.
А с подобным дублированием справляется шаблон std::enable_if[?]. Часто его используют для выбора поведения шаблона исходя из черт аргумента шаблона.

В твоем же случае можно успешно применять между реализацией с полем и реализацией без поля.
Например, в виде такого упрощения определять общее поведение всего типа.

Отсюда:
соответственно во всех методах, где этот член используется можно будет проверку if constexpr (someCondition)

Я подобные блоки кода называю замусореванием. Это как будто шел человек, захотел есть, пошел к палатке, купил еду, поел, а обертку и все остальное кинул прямо перед палаткой. Намусорил и ушел.
Вот и писатель кода нередко в пылу решения задачи заходит в код, что-то дописывает, решает свои житейские проблемы и в результате код становится замусоренным. В коде больше не видно поведения, в коде появляются всякие сервисные штуки для этого кода. Код становится тяжело читать. А шаблонный код всегда и вдвойне тяжелее читать.

За чистотой кода нужно следить. Подобные вещи, как вот такие блоки if constexpr, нужно убирать в функции. А где эти функции лучше расположить? Верно - прямо там, где для их работы определены данные. Поэтому на самом деле if constexpr не нужен. Нужно определить набор функций с поведением там где оно возможно. А где нет - определить заглушки чтобы клиентский, относительно вариативного поведения, код не нуждался в проверках и мог просто обращаться к вариативному поведению так, как будто оно не вариативно и есть всегда.
Опять же, тут хорошо подходит пример с DebugName[?], в котором такие заглушки реализованы.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы