Search code examples
c++variadic-templatesc++20default-argumentsstd-source-location

How to use source_location in a variadic template function?


The C++20 feature std::source_location is used to capture information about the context in which a function is called. When I try to use it with a variadic template function, I encountered a problem: I can't see a place to put the source_location parameter.

The following doesn't work because variadic parameters have to be at the end:

// doesn't work
template <typename... Args>
void debug(Args&&... args,
           const std::source_location& loc = std::source_location::current());

The following doesn't work either because the caller will be screwed up by the parameter inserted in between:

// doesn't work either, because ...
template <typename... Args>
void debug(const std::source_location& loc = std::source_location::current(),
           Args&&... args);

// the caller will get confused
debug(42); // error: cannot convert 42 to std::source_location

I was informed in a comment that std::source_location works seamlessly with variadic templates, but I struggle to figure out how. How can I use std::source_location with variadic template functions?


Solution

  • The first form can be made to work, by adding a deduction guide:

    template <typename... Ts>
    struct debug
    {    
        debug(Ts&&... ts, const std::source_location& loc = std::source_location::current());
    };
    
    template <typename... Ts>
    debug(Ts&&...) -> debug<Ts...>;
    

    Test:

    int main()
    {
        debug(5, 'A', 3.14f, "foo");
    }
    

    DEMO