Victor Kolesnikov
Victor Kolesnikov

Reputation: 13

A templated function that receives std::pair as an argument and deduces the types from braced-list initialization

I'm trying to create a templated function that receives an std::pair and I want the types to be
deduced implicitly without specifying them when I call the function with braced list initialization. I've tried the following code but it doesn't compile (I'm using visual studio 2017).
I'd love some help making this work.
Thanks.

template <typename Key, typename Value>
void foo(std::pair<Key, Value> arg)
{}

int main()
{
    foo({1.0, "some string"}); // doesn't compile
    foo(std::pair{ 1.0, "some string" }); // compiles when I specify the type this way
    return 0;
}

Upvotes: 1

Views: 62

Answers (1)

lubgr
lubgr

Reputation: 38267

Initializer lists induce a so-called "non-deduced context", they don't play well with template argument deduction. You can instead provide an additional overload

template <typename Key, typename Value>
void foo(Key&& k, Value&& v)
{
   foo(std::make_pair(std::forward<Key>(k), std::forward<Value>(v)));
}

which simply forwards the call to your original function template and which can be invoked via

foo(1.0, "some string");

Note that the call syntax omits the braces. You can of course put the original foo implementation right into the body of this new function template, if you prefer to have only one template.

Upvotes: 1

Related Questions