Why can't I create an instance of a class initialized with an initialization list in the constructor of another class without explicitly specifying the type?
#include <map>
#include <optional>
#include <string>
int main()
{
std::map<std::string, int> m1({{"test1", 1}, {"test2", 2}, {"test3", 3}});
std::map<std::string, int> m2{{"test1", 1}, {"test2", 2}, {"test3", 3}};
auto m3 = std::map<std::string, int>({{"test1", 1}, {"test2", 2}, {"test3", 3}});
using map_type = std::pair<const std::string, int>;
std::optional<std::map<std::string, int>>omt1(std::in_place ,{map_type{"test1", 1}, map_type{"test2", 2}, map_type{"test3", 3}});
std::optional<std::map<std::string, int>>omt2{std::in_place ,{map_type{"test1", 1}, map_type{"test2", 2}, map_type{"test3", 3}}};
auto omt3 = std::optional<std::map<std::string, int>>(std::in_place ,{map_type{"test1", 1}, map_type{"test2", 2}, map_type{"test3", 3}});
std::optional<std::map<std::string, int>>om1(std::in_place ,{{"test1", 1}, {"test2", 2}, {"test3", 3}});
std::optional<std::map<std::string, int>>om2{std::in_place ,{{"test1", 1}, {"test2", 2}, {"test3", 3}}};
auto om3 = std::optional<std::map<std::string, int>>(std::in_place ,{{"test1", 1}, {"test2", 2}, {"test3", 3}});
return 0;
}
compiller error:
main.cpp:18:107: error: no matching function for call to ‘std::optional, int> >::optional(const std::in_place_t&, )’
18 | std::optional<std::map<std::string, int>>om1(std::in_place ,{{"test1", 1}, {"test2", 2}, {"test3", 3}});
| ^
You can make use of the (C++17) deduction guides for std::optional as follows:
std::optional o(
std::map<std::string, int>{{"test1", 1}, {"test2", 2}, {"test3", 3}}
);
Live demo: https://godbolt.org/z/rfK3WxYqT
The type of the map is written only once, and there is no need for your map_type.
UPDATE
As already mentioned, the problem with your definition:
std::optional<std::map<std::string, int>> om1(
std::in_place ,{{"test1", 1}, {"test2", 2}, {"test3", 3}}
);
is that a compiler is not able to deduce the template argument for std::initializer_list. A simple demo of this problem:
template <typename T>
void f(std::initializer_list<T>) { }
int main()
{
f({1, 2, 3}); // OK; T deduced as int
f({{1, 1}, {2, 2}, {3, 3}}); // ERROR
}
Live demo: https://godbolt.org/z/KofYjdz6v
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With