用一个表达式包装变元宏中的每个元素
Wrap each element in variadic macro with an expression
问题:
我想写一个可变宏
#define WRAP(token, ...)
当使用令牌和N个参数调用时
WRAP(decltype, a, b, c)
将展开为包含在令牌中的参数的逗号分隔列表
decltype(a), decltype(b), decltype(c)
这将允许我写下如下内容:
#define MACRO(...)
Class< WRAP(decltype, __VA_ARGS__) >::Function();
如果我这样称呼它:
MACRO(a, b, c)
它将导致:
Class<decltype(a), decltype(b), decltype(c)>::Function(0;
我不知道如何做到这一点。有可能吗?也许是BOOST_PP
或类似的?
动机:
我有一个用于日志记录的宏:
#define LOG(fmt, ...)
logger::instance().push(__FUNCTION__, fmt, __VA_ARGS__);
我有一个可变的类模板,它能够验证参数是否与提供的格式字符串匹配
template<typename... Ts>
struct Format
{
template<std::size_t N>
static constexpr bool check(const char (&fmt)[N], std::size_t n);
};
如果我用固定数量的参数定义一个宏,我可以调用我的格式检查函数:
#define LOG(fmt, a)
static_assert(Format<decltype(a1)>::check(fmt, 0), "");
logger::instance().push(__FUNCTION__, fmt, a);
然而,如果我使用可变宏,这不会适用于超过1个参数:
#define LOG(fmt, ...)
static_assert(Format<decltype(__VA_ARGS__)>::check(fmt, 0), "");
logger::instance().push(__FUNCTION__, fmt, __VA_ARGS__);
这是因为decltype(__VA_ARGS__)
显然是无效语法。
要修复它,我需要将__VA_ARGS__
扩展为decltype(a1), decltype(a2), decltype(a3)
变分函数模板
我曾尝试使用constexpr
可变函数模板来实现这一点,但我无法将fmt
传递给static_assert
,因为它在这一点上不再是字符串文字:
template<size_t N, typename... Ts>
constexpr void check(const char (&fmt)[N], const Ts&...)
{
static_assert(Format<Ts...>::check(fmt, 0), "");
}
尝试调用此检查函数
check("%s", "hello world");
编译失败:
main.cpp:216:46: in constexpr expansion of ‘Format<T, Ts ...>::check<7ul>((* & fmt), 0ul)’
main.cpp:216:5: error: ‘fmt’ is not a constant expression
使用Boost.PP:非常简单
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#define COMMA_SEP(r, token, i, e) BOOST_PP_COMMA_IF(i) token(e)
#define WRAP(token, ...) BOOST_PP_SEQ_FOR_EACH_I(COMMA_SEP, token, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
编辑:如果__VA_ARGS__
为空,以上内容将不起作用,要解决此问题,请参阅此解决方案,但请注意,该解决方案不适用于MSVC,因为它们的预处理器不符合标准,如果您想支持MSVC,只需使用BOOST_PP_IS_EMPTY
代替ISEMPTY
。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- 如何在c++17中制作一个模板包装器/装饰器
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 通过Overloading Operator []访问自定义数组包装器中的元素
- 用一个表达式包装变元宏中的每个元素
- 访问向量 c++11 中的引用包装元素
- 增强 MPL 将每个元素包装在一个集合中
- 为什么分配给AVX矢量包装类对象数组的元素会引发访问违规错误
- D3D11_INPUT_ELEMENT_DESC:元素类型/排序/包装
- 如何使用c++ Mat类ptr对象的基本C包装器打印Mat元素?