vsoftco
vsoftco

Reputation: 56547

Extract template type from initializer list

I have a problem with C++11 templated code. I have a template function

    template <typename T> 
    f(const std::vector<T>& v)
    {
      /* do something here*/
    };

When I invoke f(v), where v is declared as std::vector<some_type> v;, the program compiles just fine. However, if I pass an initializer list to f, say f({a,b,c}), where a, b, c are all of the same type, say some_type, I get a compile error: couldn't infer template argument 'T', so I have to manually specify the type when invoking f. That is, for example, f<int>({a,b,c}); compiles just fine when a, b and c are all ints. Is there any way of inferring the template type T from a standard initializer list given that the function is defined as taking a parameter of std::vector<T>? Basically I just want to be able to invoke f({initializer_list}); without specifying the type of the elements of the initializer_list in angle brackets when invoking f.

Upvotes: 3

Views: 815

Answers (2)

rici
rici

Reputation: 241691

You could just define

template<typename T>
void f(const std::initializer_list<T>& v) {
  f(std::vector<T>(v));
}

For this to work, the initializer_list has to be of some unambiguous type, so f({0, 1.41421, 2.71828, 3.14159 }) won't work, but f({0.0, 1.41421, 2.71828, 3.14159}) will.

Upvotes: 5

R Sahu
R Sahu

Reputation: 206567

In an answer to another SO post, jogojapan said,

The brace-init-list {...} is the new uniform initialization syntax for C++11, and it can be used to initialise any automatic, static or member variable if the type of that variable is known.

Since the type of the argument being passed is known when you call:

f<int>({a,b,c});

it works.

When you use:

f({a,b,c});

the type has to be deduced. Hence, it does not work.

If you want to take advantage of type of a, you can use:

f<decltype(a)>({a,b,c});

That should work.

Upvotes: 1

Related Questions