Базовый класс должен возвращать авто-тип на основе производного определенного типа - PullRequest
1 голос
/ 24 марта 2019

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

Я пробовал разные подходы к проектированию с шаблонами и вычетами типов ... Также пытался сохранить фактическое значение в контейнере вложенного класса.

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

Базовый класс

class IAlpha
{
public:
    virtual auto Get() = 0;
};

Производный класс

template< typename T >
class Alpha:
    public IAlpha
{
    T x;
public:
    Alpha( T _x ):x(_x)
    {

    }

    auto Get() ->decltype(x) override
    {
        return x;
    }
};

Main

    IAlpha *i = new Alpha<int>(1);
    IAlpha *d = new Alpha<double>(1.0);


    int x = i->Get();
    double y = d->Get();

Ошибка Iget at IAlpha :: Get () «Функция с выведенным типом возврата не может быть виртуальной»

Я понимаю проблему, и ее можно решить, например,

virtual auto Get()->decltype(  "TYPE"  ) = 0;

Но проблема в том,Интерфейс не знает ТИПА, и он не должен поддерживать его универсальным ....

Обратите внимание, std::variant & std::any, к сожалению, нет вариантов в моем приложении.

1 Ответ

0 голосов
/ 24 марта 2019

Это решение не идеально ... но оно подойдет.

#include <iostream>
#include <assert.h>
#include <vector>

template< typename T >
class Param;

class IParam
{
protected:

public:

    template< typename T>
    const T& Get()
    {
        return static_cast< Param<T>* >(this)->Read();
    };
};


template< typename T >
class Param:
    public IParam
{
    T *x;
public:
    Param()
    {
        x = new T();
    }

    void Set( T _v)
    {
        *x = _v;
    }

    const T& Read()
    {
        return *x;
    }
};

// This vector will be a Singleton Parameter Manager
std::vector<IParam*> mParameters;

class Alpha
{
private:
    Param<int> *param;
public:
    Alpha()
    {
        param = new Param<int>();
        mParameters.push_back( param );
    }

    void Set()
    {
        param->Set(1);
    }
};

int main ()
{
    std::cout << "Starting Sandbox" << "\n";

    Alpha *a = new Alpha();

    // Attach to the Alpha parameter
    const int& i = mParameters[0]->Get<int>();

    // Print 0
    std::cout << i << std::endl;
    a->Set();

    // Print 1
    std::cout << i << std::endl;
    return 0;
}
...