Search code examples
c++templatesc++14variadic-templatestemplate-argument-deduction

Implicit conversions with variadic templates


Consider two function calls

foo({"a", 1}, {"b", "value"});
foo({"a", 1}, {"b", "value"}, {"c", 1.0});

Is there a way to write function foo for arbitrary number of argument pairs?

I was thinking something along the lines

template <typename... Args>
void foo(std::pair<const char*, Args>&&...);

which unfortunately does not work.

gcc fails with an error:

error: too many arguments to function 'void foo(std::pair<const char*, Args>&& ...) [with Args = {}]'
 foo({"aa", 1});

Solution

  • To expand a bit on Edgar Rokyan's answer, you can move the pair creation into the foo function:

    template<typename... Args>
    void foo() {}
    
    // Forward declaration
    template<typename U, typename... Args>
    void foo(const char * str, U u, Args... args);
    
    // When given a pair
    template<typename U, typename... Args>
    void foo(const std::pair<const char *, U>& p, Args... args) {
        std::cout << p.first << " = " << p.second << std::endl;
        foo(args...);
    }
    
    // when given a C string and something else, make a pair
    template<typename U, typename... Args>
    void foo(const char * str, U u, Args... args) {
        foo(std::make_pair(str, u), args...);
    }
    

    Then you can call it like:

    foo("hi", 42,
        "yo", true,
        std::make_pair("Eh", 3.14),
        "foo", false,
        some_pair);