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



我想选择调用函数或将其转换为字符串(打印出)。以下是行不通的:

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

有什么想法?

如果您可以使用variadic模板而不是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,以便为任何返回类型f都可以很好地定义l

最后,如果未定义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的策略与以前相同的策略,但是在这种情况下,我们将每个参数转发给您的记录器。

最新更新