C++ Гетерогенный список

В течение нескольких недель я искал в Интернете о разнородных списках (vector, array, list) в C ++, однако, на всех сайтах и ​​форумах ответ один и тот же: boost::any, но я хотел сделать это на чистом C ++. Я разработал это:

#include <iostream>
#include <typeinfo>
#include <vector>

using namespace std; 
 //Compiler version g++ 6.3.0

 class any
 {
 public:
    auto get() {}
 };

 template<typename T>
 class anyTyped : public any
 {
 public:
    T val;

    anyTyped(T x)
    {
        val = x;
    }
    T get()
    {
        return val;
    }
 };

 class queue
 {
    vector<any*> x;
    int len = 0;

 public:
    queue()
    {
        x.resize(0);
    }

    template<typename T>
    void insert(T val)
    {
        any* ins = new anyTyped<T>(val);
        x.push_back(ins);
        len++;
    }
    int size()
    {
        return len;
    }

    auto& at(int idx)
    {
        return x[idx]->get();
    }
 };

 int main()
 {

    queue vec;

    vec.insert(5);     //int
    vec.insert(4.3);   //float
    vec.insert("txt"); //string

    for (int i = 0; i < vec.size(); i++)
    {
        cout << vec.at(i);
    }

    return 0;
 }

Но я получаю эту ошибку:

source_file.cpp: In member function 'auto& queue::at(int)':
source_file.cpp:55:23: error: forming reference to void
    return x[idx]->get();
                       ^
source_file.cpp: In function 'int main()':
source_file.cpp:70:9: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'void')
    cout << vec.at(i);
    ~~~~~^~~~~~~~~~~~

Я знаю, что проблема в использовании auto в качестве типа возврата, либо в auto get() в any класс или в auto& at(int idx) в queue класс, но я не знаю, как исправить.

2 ответа

Решение

Для сохранения все разнородные данные должны быть сведены к чему-то однородному в C++. std::any не является исключением. Чтобы сделать вещи однородными, есть, самое главное, наследование и стирание типа (any это пример последнего).

Применительно к вашему примеру это может означать, например, что вы должны указать тип возвращаемого значения get к фиксированному типу. В лучшем случае это будет std::common_type всех ваших используемых типов T,

Чтобы получить идею:

anyTyped<double> anyDouble{1.0};
anyTyped<int> anyInt{2};

std::vector<std::function<double()> > anyStore;  //the chosen homogenous type is 'double'

//get() should be const, otherwise add a 'mutable'
anyStore.push_back([anyDouble]() { return anyDouble.get(); });
anyStore.push_back([anyInt]() { return anyInt.get(); });

Теперь вы можете позвонить

auto x = anyStore[0]();   //x is a double
x = anyStore[1]();

Вы получаете double в обоих случаях, но вы не получите обратно свой int,

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

В твоем any класс, и я бы порекомендовал вам решить эти проблемы, прежде чем добавить его в очередь.

Основная проблема заключается в том, что C++ является статически типизированным языком и извлекает значения из vec.at(i) скорее всего, потребуется какая-то информация о наборе: vec.at<int>(i),

Ваш any Реализация будет намного более надежной и разумной, чтобы работать так, как вы собираетесь. использование boost/any.hpp или же std::any, Если вы не хотите включать всю надстройку, попробуйте включить только заголовок any или найти реализацию заголовка с одним заголовком. any библиотека.

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

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

http://www.boost.org/doc/libs/1_55_0/boost/any.hpp

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

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