How to specialize a variadic template function in c++?

Let the function foo be given with the following "signature":

template<typename ...Ts>
void foo(Ts ...args)

This is a bit overdone since I need foo to proccess doubles only. How can I modify foo so it accepts doubles only?

The original code has been Godbolted:

#include <tuple>
#include <iostream>

template<typename ...Ts>
void foo(Ts ...args)
{
    std::tuple<Ts...> tu(args...);
    std::apply([](Ts const&... tupleArgs)
        {
            ((std::cout << tupleArgs << " "), ...);
        }, tu);
}

int main()
{
    foo(-2.44, -5.66, 78.99);
}

The output reads:

-2.44 -5.66 78.99

2 answers

  • answered 2020-11-25 07:16 cigien

    You can constrain your template like this:

    template<typename ...Ts>
    requires std::conjunction_v<std::is_same<double, Ts>...>
    void foo(Ts ...args)
    {
      // ...
    }
    

    Here's a demo

    As pointed out by HolyBlackCat, you can write the template much more conveniently like this:

    void foo(std::same_as<double> auto ...args)
    {
        (std::cout << ... << args);
    }
    

    Note also that you can use a fold expression to print the arguments.

    Here's a demo.

  • answered 2020-11-25 07:37 Keijo

    Those of us who are still stuck with C++17 will have to do with a slightly uglier syntax :(

    template<typename ...Ts>
    std::enable_if_t<std::conjunction_v<std::is_same<Ts, double>...>> foo(Ts ...args)
    {
        (std::cout << ... << args);
    }