Как работать с переменной const в шаблонном коде?

У меня есть шаблонный класс myClass, и я собираюсь использовать его для двух конкретных типов.

Проблема в том, что должно ли что-то быть const в myClass, зависит от того, создан ли он с первым типом (в котором почти все является const) или вторым типом (в котором почти все не является константой).

Как мне решить эту проблему? Кажется, есть два возможных подхода.

Я мог бы написать const в шаблонном коде, как если бы он был для первого типа (тот, который на самом деле является константой), а затем каким-то образом «выбросить» все эти константы, как только я создам экземпляр со вторым типом? Это возможно?

Второй подход состоит в том, чтобы вообще не писать const, а затем, когда я создаю экземпляр myClass с первым типом, я создаю сам весь объект const. Кажется, это немного компенсирует отсутствие константной корректности в самой реализации класса ...

А может я еще что-нибудь сделаю?

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

Пожалуйста, покажите нам настоящий класс.

Cortex0101 31.10.2018 13:17

вы можете взглянуть на std::conditional и std::is_same. Чтобы получить более конкретный ответ, рассмотрите возможность добавления минимальный воспроизводимый пример

463035818_is_not_a_number 31.10.2018 13:18

Я бы еще добавил std :: is_const

Dan M. 31.10.2018 13:18

хотя я бы рекомендовал пересмотреть, действительно ли реализация с const и одна без для двух разных типов действительно лучше всего реализована в качестве шаблона

463035818_is_not_a_number 31.10.2018 13:19
2
4
68
2

Ответы 2

Используйте класс type_traits.

Начните с пустого класса typetraits, а затем специализируйте его на своем первом типе. Поместите туда все нужные вам типы с помощью const.

Затем снова специализируйте его для вашего второго типа и поместите туда типы без const.

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

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

struct RequiresConst
{};

struct OtherStruct
{};

Затем вы можете написать несколько удобных шаблонов, например:

template<class T, bool B>
using conditional_const = typename std::conditional<B, const T, T>::type;

template<class T>
constexpr bool needsConst = std::is_same_v<T, RequiresConst>;

Это позволяет вам естественным образом сформулировать то, что вы хотите:

template<class T>
struct MyClass
{
    conditional_const<int, needsConst<T>> member;
};

Демо (включая тест).

Обратите внимание, что это работает только для переменных-членов. Я не знаю, как сделать функции const или не-const таким же удобным способом. Но вы можете написать константную и неконстантную версию для каждой функции и включить ровно одну из каждой пары через std::enable_if (или какой-либо другой SFINAE).

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

Другие вопросы по теме