Шаблонная функция для возврата контейнеров несвязанных типов - PullRequest
0 голосов
/ 28 мая 2020

У меня есть несколько контейнеров не связанных типов. Я хотел бы написать шаблонную функцию для обработки входных значений и вставки их в соответствующие контейнеры. На данный момент это моя лучшая попытка:

#include <iostream> 
#include <set>

struct A {
  // Must have operator< or std::less to insert into a std::set
  // Probably a bad idea to do it by memory address
  bool operator<(A const& other) const { return this < &other; }
};
struct B {
  bool operator<(B const& other) const { return this < &other; }
};
struct C {
  bool operator<(C const& other) const { return this < &other; }
};

std::set<A> aSet; 
std::set<B> bSet;
std::set<C> cSet;

template 
<typename T> 
std::set<T>& getSet();

template 
<> 
std::set<A>& getSet<A>() { return aSet; }

template 
<> 
std::set<B>& getSet<B>() { return bSet; }

template 
<> 
std::set<C>& getSet<C>() { return cSet; }

template 
<typename T> 
void process(T const& value) { 
  std::set<T>& specializedSet(getSet<T>());
  specializedSet.insert(value); 
}

int main() 
{ 
  // do stuff
  process(A()); process(A()); process(A());
  process(B()); process(B());
  process(C());

  std::cout<<"Set has "<<getSet<A>().size()<<" element(s)\n"
           <<"Set has "<<getSet<B>().size()<<" element(s)\n"
           <<"Set has "<<getSet<C>().size()<<" element(s)"<<std::endl;
} 

Он дает ожидаемый результат:

Set has 3 element(s)
Set has 2 element(s)
Set has 1 element(s)

Я бы сильно предпочел не специализироваться на getSet() для каждого типа (я действительно есть 10), хотя иметь возможность использовать шаблон process() стоит. В идеале мне даже не нужно было бы объявлять отдельные контейнеры aSet, bSet, et c. Я мог бы сделать все эти указатели типов, если бы это было полезно, хотя я бы хотел держаться подальше от set::set<void*> или аналогичного непрозрачного кода, если это возможно. Если это дубликат, прошу прощения, его немного сложно найти.

Ответы [ 2 ]

2 голосов
/ 28 мая 2020

В C ++ 14 вы можете использовать переменную шаблона:

template <typename T>
std::set<T> mySet{};

Раньше вы могли заключить ее в функцию шаблона:

template <typename T>
std::set<T>& getSet() { static std::set<T> instance; return instance; }
2 голосов
/ 28 мая 2020

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

template<typename T>
std::set<T>& getSet()
{
    static std::set<T> s;
    return s;
}

Это создаст новый std::set для типа T, при первом вызове getSet<T>().

...