1

I am sure there is a an easy way to do this but couldn't find anything in SO. Couldn't find much info in en.cppreference.com either.

Is there a way to simplify the std::variant</*class types*/> so that we can declare functions and classes that could take the same std::variant as an argument.

Consider this example:

I have a vector which acts as a container for the following std::variant;

std::vector<std::variant<Car, Space, Human>> EntityContainer;

if I want to pass this vector to a function as an argument, I have to do add the following parameter declaration.

void Function(std::vector <std::variant<Car, Space, Human>>& container);

I could perhaps use macros for this example but this doesn't really solve the problem.

Is there a better solution to this rather than listing same class types in std::variant over and over again everywhere around the project?

code live

#include <iostream>
#include <vector>
#include <variant>


class Human
{
public:
  void Talk(){ std::cout << "whass up\n"; }
};
class Car
{
public:
  void RunEngine() { std::cout << "Vroom\n"; }
};
class Space
{
public:
  void Expand() { std::cout << "Expand slowly\n"; }
};

struct VisitPackage
{
  void operator()(Human& obj) { obj.Talk();}
  void operator()(Car& obj) { obj.RunEngine();}
  void operator()(Space& obj) { obj.Expand();}
};  

void Function(std::vector <std::variant<Car, Space, Human>>& container)
{
  for (auto& entity : container)
  {
    std::visit(VisitPackage(), entity);
  }
}
int main()
{
  std::vector<std::variant<Car, Space, Human>> EntityContainer;
  EntityContainer.emplace_back(Car());
  EntityContainer.emplace_back(Human());
  EntityContainer.emplace_back(Space());
  Function(EntityContainer);

  return 0;
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
Yucel_K
  • 688
  • 9
  • 17
  • 3
    1) use `using` type alias, 2) use `template`. – Evg Oct 08 '18 at 19:19
  • @JeJo That coded you added was not the OP's. They linked to just wandbox, not their actual code so what you added is what you had in there the last time you visited wandbox. – NathanOliver Oct 08 '18 at 19:25
  • @NathanOliver that was my bad. didn't realise that the link was just for the wandbox. i don't think i need to edit the question but here is the link just for completeness https://wandbox.org/permlink/8lsnONaTfB8oyl2u – Yucel_K Oct 08 '18 at 19:44

1 Answers1

8

You're looking to define aliases. This can be done with using or typedef. using is more familiar to C++ programmers because of its syntax, typedef is C-compatible.

typedef std::variant<int, double, float> arithmetic;
using arithmetic = std::variant<int, double, float>;
//Both are equivalent

std::vector<arithmetic> entityContainer;
void function(std::vector<arithmetic> const& vector) {
    /*...*/
}
Xirema
  • 19,889
  • 4
  • 32
  • 68
  • 6
    C compatibility doesn't mean much if you are using C++. `typedef std::anything foo` is never valid C, and `typedef anything foo` is never valid C. – Justin Oct 08 '18 at 19:22
  • i never knew i could use `using` this way in c++. thanks for the info. that pretty much solves it! – Yucel_K Oct 08 '18 at 19:24