Arhn - архитектура программирования

Как я могу специализировать тип операторной функции по шаблону класса

У меня есть класс, подобный следующему, и я хочу специализировать оператор '->' по шаблону класса T. Специализация должна зависеть от того, является ли тип T типом указателя или нет. Я искал решения, но не нашел их для этой конкретной проблемы.

template <typename T>
class C
{
public:
    // when T is a pointer type
    T operator->()
    {
        return value;
    }

    // when T is not a pointer type
    const T* operator->() const
    {
        return &value;
    }

private:
    T value;
};

void test()
{
    struct Test
    {
        int x, y;
    };

    C<Test> c1;
    C<Test*> c2;

    c1->x = 5; // should both work
    c2->x = 5; // ignoring the fact, that c2's value is undefined
}

Спасибо за любую помощь!

05.05.2019

  • if constexpr будет чистым, если вас устроит c++17 решение. 05.05.2019
  • @super Конечно, не могли бы вы привести пример? 05.05.2019

Ответы:


1

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

template <typename T>
class C
{
public:
    explicit C(const T& v = T()): value(v) {}
    // when T is not a pointer type
    T* operator->()
    {
        return &value;
    }

private:
    T value;
};

template <typename T>
class C<T*>
{
public:
    explicit C(T* v = nullptr): value(v) {}
    // when T is a pointer type
    T* operator->()
    {
        return value;
    }

private:
    T* value;
};

Или, если у вас есть компилятор, совместимый с C++17, вы можете использовать if constexpr:

template <typename T>
class C
{
public:
    explicit C(const T& v = T()): value(v) {}
    // when T is not a pointer type
    auto operator->()
    {
        if constexpr (std::is_pointer_v<T>)
            return value;
        else
            return &value;
    }

private:
    T value;
};

Чтобы проверить это:

int main()
{
    struct Test
    {
        int x, y;
    };

    C<Test> c1({1, 2});
    Test t = {3, 4};
    C<Test*> c2(&t); // Initialize the pointer with some valid address, we are going to dereference it!

    c1->x = 5;
    c2->x = 5;
    std::cout << c1->x << ' ' << c1->y << ' ' << t.x << ' ' << t.y << '\n';
}
05.05.2019
Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..