Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::format with variadic template arguments

Suppose I have a printf-like function (used for logging) utilizing perfect forwarding:

template<typename... Arguments>
void awesome_printf(std::string const& fmt, Arguments&&... args)
{
    boost::format f(fmt);
    f % /* How to specify `args` here? */;
    BlackBoxLogFunction(boost::str(f).c_str());
}

(I didn't compile this but my real function follows this guideline)

How can I "unroll" the variadic argument into the boost::format variable f?

like image 593
void.pointer Avatar asked Sep 16 '14 02:09

void.pointer


Video Answer


2 Answers

I did some googling and found an interesting solution:

#include <iostream>
#include <boost/format.hpp>

template<typename... Arguments>
void format_vargs(std::string const& fmt, Arguments&&... args)
{
    boost::format f(fmt);
    int unroll[] {0, (f % std::forward<Arguments>(args), 0)...};
    static_cast<void>(unroll);

    std::cout << boost::str(f);
}

int main()
{
    format_vargs("%s %d %d", "Test", 1, 2);
}

I don't know if this is a recommended solution but it seems to work. I don't like the hacky static_cast usage, which seems necessary to silence the unused variable warnings on GCC.

like image 118
void.pointer Avatar answered Sep 28 '22 03:09

void.pointer


As is usual with variadic templates, you can use recursion:

std::string awesome_printf_helper(boost::format& f){
    return boost::str(f);
}

template<class T, class... Args>
std::string awesome_printf_helper(boost::format& f, T&& t, Args&&... args){
    return awesome_printf_helper(f % std::forward<T>(t), std::forward<Args>(args)...);
}

template<typename... Arguments>
void awesome_printf(std::string const& fmt, Arguments&&... args)
{
    boost::format f(fmt);

    auto result = awesome_printf_helper(f, std::forward<Arguments>(args)...);

    // call BlackBoxLogFunction with result as appropriate, e.g.
    std::cout << result;
}

Demo.


In C++17, simply (f % ... % std::forward<Arguments>(args)); will do.

like image 29
T.C. Avatar answered Sep 28 '22 03:09

T.C.