Альтернативы представлению параметра шаблона из составного класса - PullRequest
1 голос
/ 07 октября 2019

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

#include <iostream>

template <typename Der>
class A : private Der {
    public:
    int get() { return Der::get_(); }
};

class B {
    protected:
    int get_() { return 20; }
};

class C {
    protected:
    int get_() { return 30; }
};

using Default = B;

template <class T = Default>
class User {
    public:
    User() {}

    A<T>& getMember() { return m_; }

    private:
    A<T> m_; // This is what I am adding, and exposing param T.
};

int main(int argc, char* argv[]) {
    User h;
    std::cout<<h.getMember().get()<<std::endl;
}

Одним из решений, которое я мог бы придумать, является использованиетипа sum, но здесь вводится некоторый код обработки исключений:

class User {
    public:
    User() : m_(A<Default>()) {}

    template <typename T>
    User(const T& in) : m_(in) {}

    template <typename T>
    A<T>& getMember() { return std::get<A<T>>(m_); }

    private:
    std::variant<A<B>, A<C>> m_;
};

Я ищу:

  • Имя того, что я пытаюсь сделать, если оно существует.
  • Способы, с помощью которых я могу достичь желаемого.

1 Ответ

0 голосов
/ 09 октября 2019

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

Что-то вроде:

#include <iostream>
#include <memory>

class User {
    public:
    template <class T>
    User(T&&) : m_(new Internal<T>()) {}

    int doOnMember() { return m_->doOnMember(); }

    private:
    class InternalBase {
        public:
        virtual int doOnMember() = 0;
    };

    template <typename T>
    class Internal : public InternalBase {
        public:
        Internal() {} 
        int doOnMember() { return m_.get(); }

        private:
        A<T> m_;
    };

    private:
    std::shared_ptr<InternalBase> m_;
};

int main(int argc, char* argv[]) {
    User h(B{});
    std::cout<<h.doOnMember()<<std::endl;
    User h1(C{});
    std::cout<<h1.doOnMember()<<std::endl;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...