Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I "map" a parameter pack

This question is similar with this, It seems in my version I need to write my own sizeof...

Suppose I have a struct Wrapper with definition

struct Wrapper{
    string s;
}

and I have a function, it accept a pack of Wrapper and printf them. Because printf take a pack of const char *, so I need to map this pack of Wrapper into a pack of const char *

template<typename ... Args>
void printf_wrapper(string format, Args&& ... args){
    printf(format.c_str(), /* #1: WHAT CAN I WRITE HERE */)
}

I heard a swallow function may help me with that, but what does it like, and how it functions?

like image 731
calvin Avatar asked Jul 27 '26 08:07

calvin


2 Answers

Using the wrapper you defined in the question, it's a matter of using this:

template<typename ... Args>
void printf_wrapper(std::string format, Args&& ... args){
    printf(format.c_str(), args.s.c_str()...);
}

As a minimal, working example:

#include <type_traits>
#include <cstdio>
#include <string>

struct Wrapper{
    std::string s;
};

template<typename... T>
constexpr bool areWrappers =
    std::is_same<
        std::integer_sequence<bool, true, std::is_same<T, Wrapper>::value...>,
        std::integer_sequence<bool, std::is_same<T, Wrapper>::value..., true>
    >::value;

template<typename ... Args>
void printf_wrapper(std::string format, Args&& ... args){
    static_assert(areWrappers<std::decay_t<Args>...>, "!");
    printf(format.c_str(), args.s.c_str()...);
}

int main() {
    printf_wrapper("%s %s", Wrapper{"foo"}, Wrapper{"bar"});
}

I added also the areWrappers utility to check that your Args are actually all Wrappers. If they are not, the solution above won't work, but the static_assert will help to get out of it a meaningful error message.


See it on wandbox.

like image 98
skypjack Avatar answered Jul 28 '26 23:07

skypjack


I suggest using a simple solution which is similar to @ildjarn's posted in the comment above.

If the Wrapper structure looks like this:

struct Wrapper {
    std::string hidden_str;
};

Then you might change the print function as below:

template<typename... Args>
void print(const std::string& format, Args const&... args) {
    printf(format.c_str(), args.hidden_str.c_str()...);
}

wandbox example

like image 29
Edgar Rokjān Avatar answered Jul 28 '26 23:07

Edgar Rokjān



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!