spraff
spraff

Reputation: 33445

Why can't this initializer-list match to a template argument?

#include <iostream>

class Foo
{
public:

    template <typename Container>
    Foo (const Container & args)
    {
        for (auto arg : args)
            std::cout << "ARG(" << arg << ")\n";
    }
};

int main ()
{
    Foo foo ({"foo", "bar", "baz"});
}

The error (using g++ -std=c++17) is

error: no matching function for call to ‘Foo::Foo(<brace-enclosed initializer list>)’

This works

Foo foo (std::vector<const char*> ({"foo", "bar", "baz"}));

Why can't the initializer-list match the template constructor?

Upvotes: 3

Views: 409

Answers (2)

max66
max66

Reputation: 66230

As explained by Jarod42, {"foo", "bar", "baz"} has no type, so it cannot be deduced for template <typename Container> Foo (const Container&).

Another possible solution is

template <typename T, std::size_t N>
Foo (T const (& arr)[N])
{
    for (auto arg : arr)
        std::cout << "ARG(" << arg << ")\n";
}

so {"foo", "bar", "baz"} is deduced as an initialization list for a C-style array with the correct size (3).

Upvotes: 1

Jarod42
Jarod42

Reputation: 218323

{"foo", "bar", "baz"} has no type, so it cannot be deduced for

template <typename Container>
Foo (const Container&);

You can only use it for deduction for

template <typename T>
Foo (const std::initializer_list<T>&);

Upvotes: 4

Related Questions