Hi there template meta programming experts.
I'm attempting to write a (class member) function the could ideally take as an argument what might be called a type agnostic map.
Ideally something like:
foo({"Bar", 42}, {"Baz", "Blargh");
as well as:
foo({"Blargh", "Bleh"}, {"Biz", 43.6}, {"Bam", {43, 43, 43}});
The class/function should then be able to convert these arguments by calling a conversion function deduced at compile time, so it would internally end up with an std::map with strings as keys and values.
The reason is simply syntactic sugar. In my use case it would be very convenient for the caller not to have to worry about converting the arguments and getting a compile time error if a non supported type was provided.
I have made it work if the caller explicitly uses make_pair as in:
foo(std::make_pair<std::string, std::chrono::miliseconds>("Time", 42));
But naturally that is not very clean and definitely not more convenient than having the caller convert the value types to std::string herself.
I have tried creating my own std::pair like class with specializations for various value types, but my compiler (gcc) is not able to find it if I call with a brace initializer just as is the case with a standard std::map. My compiler seems to see it as an std::initializer_list even if the arguments have different types.
I have more or less come to the conclusion that what I'm trying is not possible with C++ even in the C++ 14 standard, but I'm not absolutely certain.
Does anyone have any ideas on how to solve this or are able to explain why this isn't possible if that is the case?
Thanks a lot!
EDIT
Example code:
template<typename Value, typename... Args>
void foo(const std::pair<std::string, Value>& val, Args... args)
{
foo(args...);
}
void foo(const std::pair<std::string, int>& val) {}
void foo(){}
Calling foo() like this:
foo({"key", 42});
doesn't expand the template and works, while:
foo({"key", 42}, {"another", 53})
fails to compile with the error:
no matching function for call to ‘foo(<brace-enclosed initializer list>, <brace-enclosed initializer list>)’