Varargs宏可以执行函数调用或将其转换为字符串

时间:2019-02-15 22:29:50

标签: c++

我想选择调用一个函数或将其转换为字符串(打印出来)。以下内容无效:

#if !defined(ENABLE_FUNCS)
#define APPLY(func, ...) do { (func(__VA_ARGS__); } while(0)
#else
#define APPLY(func, ...) \
  do {std::clog << #func << #__VA_ARGS__ << std::endl;} while(0)
#endif
...

APPLY(openlog, ((name.size() ? name.data() : nullptr), flags, facility);

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

如果您愿意使用可变参数模板而不是VA_ARGS,请考虑以下ENABLE_FUNCS情况的定义:

template <typename F, typename... Args>                     
void apply(F&& f, Args&&... args) {                         
    std::initializer_list<int> l{                           
        (std::forward<F>(f)(std::forward<Args>(args)), 0)...
    };                                                      
    (void) l;  // Silence compiler warnings                                             
}                                                           

std::initializer_list为我们提供了一种以给定顺序针对每个参数调用f的方法。我们对逗号运算符使用了一些技巧,使表达式的计算结果为int,以便为l可能具有的任何返回类型定义f

最后,如果未定义ENABLE_FUNCS,则可以提供apply的以下定义:

template <typename F, typename... Args>          
void apply(F&&, Args&&... args) {                
    std::initializer_list<int> l{                
        (cout << std::forward<Args>(args), 0)... 
    };                                           
    cout << endl;                                
    (void) l;                                    
}                                                

我们使用与initializer_list相同的策略,但是在这种情况下,我们会将每个参数转发给记录器。