Home > Net >  Constructing std::map wrapped with std::optional with std::initializer_list
Constructing std::map wrapped with std::optional with std::initializer_list

Time:10-18

What kind of constructor is missing in std::optional to be able to do this:

std::optional<std::map<char, int>> get_map()
{
    return { { 'a', 1 }, { 'b', 2 }, { 'c', 3 } };
}

CodePudding user response:

You might want to do this:

#include <initializer_list>

template<class T>
struct optional {
  optional(std::initializer_list<typename T::value_type> il) : value(il)  { }
  T value;
};

#include <map>
optional<std::map<char, int>> get_map() {
  return { { 'a', 1 }, { 'b', 2 }, { 'c', 3 } };
}

#include <vector>
optional<std::vector<int>> get_vector() {
  return { 1, 2, 3 };
}

Demo.

CodePudding user response:

std::optional<std::map<char, int>> get_map()
{
  return std::optional<std::map<char, int>>(
std::in_place_t{}, {std::pair<const char,int>{'a',1}, { 'b', 2 }, { 'c', 3 }  }
  );
}
std::optional<std::map<char, int>> get_map()
{
  return std::map<char, int>{{'a',1}, { 'b', 2 }, { 'c', 3 } };
}

The core problem is that the constructors you would want are either marked explicit or have deduced parameters.

template<class T>
struct fake_opt:std::optional<T>{
  fake_opt(T&&t):std::optional<T>(std::move(t)){}
  using std::optional<T>::optional;
};

fake_opt<std::map<char, int>> get_map()
{
  return {{{'a',1}, { 'b', 2 }, { 'c', 3 }}};
}

This has a T&& ctor and an extra set of {}. Doing so to optional would probably work. I use a similar overload when I want a wrapped {} to work.

I strongly, strongly advise against even attempting to not having those extra {}. You are a box containing a chicken, not a chicken.

  • Related