将多个参数作为单个宏参数传递
Passing multiple parameters as a single macro argumment
问题
C预处理器有一个#
,它可以将后面写的任何表达式转换为原始字符串。例如:
#define make_string(x) #x
int a , b;
const char my_string[] = make_string( a + b ); //my_string holds "a + b"
有什么方法可以执行反向过程吗
我的意思是,获取一个原始字符串并将其转换为一个安全的令牌。例如(~#
是执行此操作的理论预处理器运算符):
#define make_tokens(x) ~#x
int a = 0 , b = 1;
int c = make_tokens( "a + b" ); //c holds 1 (The result of a + b addition)
某些上下文(或者">我陷入XY问题?")
我正在编写一个模板元编程库,该库主要基于定义元函数并专门化它们以获得不同的行为(如函数重载)
例如:
//Metafunction declaration:
template<typename T , typename U>
struct better_type;
//Metafunction specialization (overload)
template<>
struct better_type<char,unsigned char>
{
using result = char;
};
该库假定元函数是任何具有result
公共别名的模板。因此,用户必须执行常见的typename function</*function argumments*/>::result
才能获得函数的结果。
为了避免这种情况,我利用了C++11模板别名,只将函数定义为两部分:
函数实现:实现函数的上述形式的元函数。
template<typename T> struct function_impl;
为了实现(重载)他自己版本的功能,用户专门使用这个模板:
template<> struct function_impl<bool> { using result = /* something */; };
函数声明:定义用户的函数接口。它只是真正的元函数的别名。
template<typename T> using function = typename function_impl<T>::result;
所以函数声明总是一对声明:函数实现和用户界面别名。
现在,我的目标是使用CPP,在一些通用whay中自动进行声明。类似于:
#define define_function( template_args , function_name , function_args )
template< template_args >
struct function_name##_impl;
template< template_args >
using function_name = typename function_name##_impl< function_args >::type
可以用作:
define_function( typename T , my_function , T );
并生成以下代码而没有任何问题:
template< typename T >
struct mi_function_impl;
template< typename T >
using mi_function = typename my_function_impl< T >::type;
但考虑一下其他用法示例:
define_function( typename T , typename U , mi_binary_function , T , U );
当然,typename T , typename U
是第一个宏论证,T , U
是第二个宏论证。但这是行不通的,因为它们被视为五种不同的宏观论点
这就是我考虑生成令牌的原因,因为有了这个功能,宏可以重新发送为:
#define define_function( template_args , function_name , function_args )
template< make_tokens(template_args) >
struct function_name##_impl;
template< template_args >
using function_name = typename function_name##_impl< make_tokens(function_args) >::type
并且多个参数将作为生成预期结果的唯一原始字符串传递:
define_function( "typename T , typename U" , mi_binary_function , "T , U" );
X/Y问题的解决方案是使用括号而不是引号:
define_function( (typename T, typename U) , mi_binary_function , (T, U) );
// yields:
template< typename T, typename U > struct mi_binary_function_impl; template< typename T, typename U > using mi_binary_function = typename mi_binary_function_impl < T, U >::type;
可以实现为:
#define strip_parens(...) __VA_ARGS__
#define define_function( template_args , function_name , function_args )
template< strip_parens template_args >
struct function_name##_impl;
template< strip_parens template_args >
using function_name = typename function_name##_impl
< strip_parens function_args >::type // end
但我们也可以自动生成参数名称(无论如何,您都可以在专业化中为它们提供新名称):
define_function(foo, (class, int, typename));
// yields:
template< class T0, int T1, typename T2 > struct foo_impl; template< class T0, int T1, typename T2 > using foo = typename foo_impl < T0, T1, T2 > :: result;
可以实现为:
#define gen_single_param_name(number_plus_2)
BOOST_PP_CAT(T, BOOST_PP_DEC(BOOST_PP_DEC(number_plus_2))) // end
#define gen_single_param(s, data, elem) elem gen_single_param_name(s)
#define gen_params_from_seq(seq) BOOST_PP_SEQ_TRANSFORM(gen_single_param, _, seq)
#define gen_single_arg(s, data, elem) gen_single_param_name(s)
#define gen_args_from_seq(seq) BOOST_PP_SEQ_TRANSFORM(gen_single_arg, _, seq)
#define define_function_impl(name, param_seq, arg_seq)
template< BOOST_PP_SEQ_ENUM(param_seq) >
struct name ## _impl;
template< BOOST_PP_SEQ_ENUM(param_seq) >
using name = typename name ## _impl
< BOOST_PP_SEQ_ENUM(arg_seq) > :: result // end
#define define_function_seq(name, param_seq)
define_function_impl(name, gen_params_from_seq(param_seq),
gen_args_from_seq(param_seq)) // end
#define define_function(name, param_list)
define_function_seq(name, BOOST_PP_VARIADIC_TO_SEQ param_list)
相关文章:
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用指向成员的指针将成员函数作为参数传递
- 如何将参数传递给正在使用模板的类
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何在 C++ 中将函数作为参数传递给函数宏
- 如何将多个函数重载作为单个参数传递?
- 通过宏将函数参数传递给函数
- 可以将逗号和参数传递到C++宏中吗?
- 让宏将迭代参数传递到通过宏变量提供的代码体中
- 如何在C++中使用单个模板参数传递两个 lambda 函数
- 将模板参数传递到 MSVC 中的宏中
- ESP8266错误:宏"min"传递了 3 个参数,但只需要 2 个参数
- 将多个参数作为单个宏参数传递
- 任何人都可以解决此GCC编译器错误:宏"min"传递了3个参数,但只需要两个参数
- 宏MOCK_METHOD传递了3个参数,但std::pair只接受了2个错误
- 有没有一种方法可以将宏名称作为参数传递给嵌套宏,而在最外层宏展开时不展开它们
- 是否可以将指向类成员的指针作为C++中的单个参数传递
- 在宏中传递"int"作为参数
- 将单个变量作为std::initializer_list作为函数参数传递