本文介绍了可变参数宏:不能通过'...'传递非平凡复制类型的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为日志记录机制编写宏.我编写了一个可变参数宏,但是它不适用于std::string.该代码如下所示:

I am trying to write a macro for logging mechanism. I wrote a variadic macro but it does not work with std::string. The code looks like the following:

#include <stdio.h>
#include <string>


#define LOG_NOTE(m, ...) printf(m, ##__VA_ARGS__)

int main()
{
    std::string foo = "random string";
    int bar = 5;
    LOG_NOTE("%s %d %s", "Hello World", bar, foo);

    return 0;
}

如果我按如下所示调用宏,则不会出现任何错误.

If I would call the macro like following, I would not get any error.

LOG_NOTE("%s %d %s", "Hello World", bar, "random string");

编译器输出:

推荐答案

不要.使用可变参数模板功能.

Don't. Use a variadic template function.

您遇到的实际问题是,您试图通过C API(printf)传递C ++对象(std::string).这是不可能的.

The actual problem you have is that you're trying to pass a C++ object (std::string) through a C API (printf). This is not possible.

您需要某种转换机制,例如:

You'd need some mechanism for conversion, for example:

#include <stdio.h>
#include <string>

template<class T>
decltype(auto) convert_for_log_note(T const& x)
{
    return x;
}

decltype(auto) convert_for_log_note(std::string const& x)
{
    return x.c_str();
}


template<class...Args> 
void LOG_NOTE(const char* format, Args&&...args)
{
    printf(format, convert_for_log_note(args)...);
}

int main()
{
    std::string foo = "random string";
    int bar = 5;
    LOG_NOTE("%s %d %s\n", "Hello World", bar, foo);

    return 0;
}

示例输出:

Hello World 5 random string

http://coliru.stacked-crooked.com/a/beb3431114833860

更新:

对于C ++ 11,您需要手工说明返回类型:

For C++11 you'll need to spell out the return types by hand:

#include <stdio.h>
#include <string>

template<class T>
T const& convert_for_log_note(T const& x)
{
    return x;
}

const char* convert_for_log_note(std::string const& x)
{
    return x.c_str();
}


template<class...Args> 
void LOG_NOTE(const char* format, Args&&...args)
{
    printf(format, convert_for_log_note(args)...);
}

int main()
{
    std::string foo = "random string";
    int bar = 5;
    LOG_NOTE("%s %d %s\n", "Hello World", bar, foo);

    return 0;
}

这篇关于可变参数宏:不能通过'...'传递非平凡复制类型的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-26 21:49