我怎样才能"映射"参数包

时间:2017-03-11 06:51:56

标签: c++ c++11 c++14 variadic-templates template-meta-programming

此问题与this类似,在我的版本中,我需要编写自己的sizeof...

假设我有一个带有定义

的结构Wrapper
struct Wrapper{
    string s;
}

我有一个功能,它接受一包Wrapperprintf他们。因为printf需要一包const char *,所以我需要将这一包Wrapper映射到一包const char *

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

我听说swallow函数可以帮助我,但它是什么样的,它是如何运作的?

2 个答案:

答案 0 :(得分:2)

使用您在问题中定义的包装器,这是使用它的问题:

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

作为一个最小的工作示例:

#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"});
}

我还添加了areWrappers实用程序,以检查您的Args实际上是否Wrapper。如果不是,上述解决方案将无效,但static_assert将有助于摆脱有意义的错误消息。

wandbox上查看。

答案 1 :(得分:1)

我建议使用一个简单的解决方案,类似于上面评论中发布的@ ildjarn。

如果Wrapper结构如下所示:

struct Wrapper {
    std::string hidden_str;
};

然后您可以更改打印功能,如下所示:

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

wandbox example