Template function overloading (generic type vs template template type) choose correct overload

Viewed 91

I have a template function which does something with a given value as long as the template type is a number:

template <typename scalar_t>
void function(scalar_t value)
{
    if constexpr (std::is_floating_point_v<scalar_t>)
    {
        std::cout << value << 'F';
    }
    if constexpr (std::is_integral_v<scalar_t>)
    {
        std::cout << value;
    }
}

And an overload for this template expecting a container containing numbers:

template <typename scalar_t, template <typename> class container_t>
void function(const container_t<scalar_t> &container)
{
    for (const auto &value : container)
    {
        function(value);
        std::cout << ' ';
    }
}

With the templates above, I call the following code:

int main()
{
    function('0');
    function(short{1});
    function(2);
    function(3l);
    function(4ll);
    function(5.f);
    function(6.);

    std::vector<int> v{7, 8, 9, 10};
    std::list<double> l{11., 12., 13., 14.};

    function(v);
    function(l);

    return 0;
}

Which gives the following output:

012345F6F

While I was expecting the following output:

012345F6F7 8 9 10 11F 12F 13F 14F 

Which means that the first template version (function(scalar_t value)) has been chosen instead of the second version (function(const container_t<scalar_t> &container)).

How can I force the second version of the template-function to be chosen for template template parameters?

1 Answers
Related