The below serialize
function doesn't match with the call.
The serialize function should match a pair that contains a std::string
and an iterable type that has a parameter.
#include <variant>
#include <string>
#include <vector>
#include <ranges>
namespace S
{
typedef int Error;
typedef std::string Json;
std::variant<Json, Error> serialize(std::pair<std::string, int> entry)
{
return std::to_string(entry.second);
}
template <template <typename> typename Container>
std::variant<Json, Error> serialize(std::pair<std::string, Container<typename Container::value_type>> entry)
{
return Json();
}
}
int main()
{
std::vector<int> v = { 1, 2, 3 };
S::serialize<std::vector<int>>(std::pair<std::string, std::vector<int>>{ "a", v });
return 0;
}
The error is error C2672: 'S::serialize': no matching overloaded function found
Any idea why? What would an workaround look like?
This is common mistake to pack in template function parameters to many details about requirement.
Make your template more general then use SFINAE to limit given template parameter.
template <typename T, typename = typename T::value_type>
std::variant<Json, Error> serialize(const std::pair<std::string, T>& entry)
{
(void)entry;
return Json();
}
Now your attempt:
template <template <typename> typename Container>
std::variant<Json, Error> serialize(std::pair<std::string, Container<typename Container::value_type>> entry)
Note you are trying explain that Container
template depends on itself Container<typename Container::value_type>>
. This self reference is like Russell's paradox.
Even assuming this is a good approach formally this should look like:
template <template <typename> typename Container>
std::variant<Json, Error> serialize(std::pair<std::string, Container<typename Container<typename Container< .... >::value_type>>::value_type>> entry)
After all Container
is template template parameter, so to use it as a type it needs template parameter.