我如何将一个大型的、经常使用的 C++ 宏转换为一个 C++ 模板或类似的?
How do I transform a large, often-used C++ macro with trivial per-use changes into a C++ template or similar?
我正在开发一个容器,它的代码类似于以下伪代码:
#define LARGE_INSERT_MACRO (ASSIGNMENT_OBJECT) \
if (some_stuff) \
{ \
... do more stuff ... \
allocator.construct(place_to_insert_to, ASSIGNMENT_OBJECT); \
... etc ... \
} \
else if (other_stuff) \
{ \
... do different stuff ... \
allocator.construct(place_to_insert_to, ASSIGNMENT_OBJECT); \
... etc ... \
} \
else \
{ \
... do other different stuff ... \
allocator.construct(place_to_insert_to, ASSIGNMENT_OBJECT); \
... etc ... \
} \
... more stuff again... \
iterator insert(the_type &object)
{
LARGE_INSERT_MACRO(object)
}
iterator insert(the_type &&object)
{
LARGE_INSERT_MACRO(std::move(object))
}
template<typename... Arguments> iterator emplace(Arguments... parameters)
{
LARGE_INSERT_MACRO(parameters...)
}
鉴于每个插入类型之前和之后的代码都是插入所必需的,在插入类型之间不会改变并且不能分解为两个单独的 'before and after' 函数,这一段怎么能(伪)代码被更改,以便它不再使用宏?
一如既往,请继续讨论将宏更改为其他代码形式的话题。
答案是完全放弃大型插入宏,让通用引用推导的奇迹为您完成所有工作:
template<class TheType>
iterator insert(TheType&& object) // object is deduced to be either r-value
// or l-value reference as required by context
{
if(some_stuff) {
...
return allocator.construct(place_to_insert_to, std::forward<TheType>(object));
} else {
... and so on
}
}
只有当它是知道它包含的类型的容器的成员函数时,调用站点上没有模板参数的 emplace 才有可能。否则你必须指定它。再次注意使用通用引用推导来完美转发参数。
template<class TheType, typename... Arguments>
iterator emplace(Arguments&&... parameters)
{
return insert(TheType(std::forward<Arguments>(parameters)...));
}
我正在开发一个容器,它的代码类似于以下伪代码:
#define LARGE_INSERT_MACRO (ASSIGNMENT_OBJECT) \
if (some_stuff) \
{ \
... do more stuff ... \
allocator.construct(place_to_insert_to, ASSIGNMENT_OBJECT); \
... etc ... \
} \
else if (other_stuff) \
{ \
... do different stuff ... \
allocator.construct(place_to_insert_to, ASSIGNMENT_OBJECT); \
... etc ... \
} \
else \
{ \
... do other different stuff ... \
allocator.construct(place_to_insert_to, ASSIGNMENT_OBJECT); \
... etc ... \
} \
... more stuff again... \
iterator insert(the_type &object)
{
LARGE_INSERT_MACRO(object)
}
iterator insert(the_type &&object)
{
LARGE_INSERT_MACRO(std::move(object))
}
template<typename... Arguments> iterator emplace(Arguments... parameters)
{
LARGE_INSERT_MACRO(parameters...)
}
鉴于每个插入类型之前和之后的代码都是插入所必需的,在插入类型之间不会改变并且不能分解为两个单独的 'before and after' 函数,这一段怎么能(伪)代码被更改,以便它不再使用宏?
一如既往,请继续讨论将宏更改为其他代码形式的话题。
答案是完全放弃大型插入宏,让通用引用推导的奇迹为您完成所有工作:
template<class TheType>
iterator insert(TheType&& object) // object is deduced to be either r-value
// or l-value reference as required by context
{
if(some_stuff) {
...
return allocator.construct(place_to_insert_to, std::forward<TheType>(object));
} else {
... and so on
}
}
只有当它是知道它包含的类型的容器的成员函数时,调用站点上没有模板参数的 emplace 才有可能。否则你必须指定它。再次注意使用通用引用推导来完美转发参数。
template<class TheType, typename... Arguments>
iterator emplace(Arguments&&... parameters)
{
return insert(TheType(std::forward<Arguments>(parameters)...));
}