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 класс, но я не знаю, как исправить.

0

Решение

Для сохранения все разнородные данные должны быть сведены к чему-то однородному в 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,

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

1

Другие решения

В твоем 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 учебный класс.

0

По вопросам рекламы [email protected]