我有一个组件地图。组件是具有一些数据的POD类型。每个组件都有唯一的标识符。地图在任何时候都只能拥有给定类型的一个组件。因此,我希望能够查询地图所拥有的组件。这是我用来完成此任务的代码:
template <typename T>
bool has()
{
auto found = map.find(T::tag);
if (found != map.end()) return true;
else return false;
}
这会导致代码笨拙,如:something.has<Component<int>>() && something.has<Component<float>>() ... etc;
为了减少代码杂乱,我想使用可变参数模板。
template <typename T, typename... Args>
bool hasz()
{
has<T>();
has<Args>()...; /* expected ‘;’ before ‘...’ token */
}
不应该has<Args>()...
扩展为(伪)has<Args[0]>(), has<Args[1]>(), etc...
(这是合法的语法)?是否可以这样做?
答案 0 :(得分:7)
是的,你只需要递归调用函数:
template <typename T>
bool has()
{
return map.end() != map.find(T::tag);
}
template <typename T, typename... Args>
bool has()
{
return has<T>() && has<Args...>();
}
您有两个版本的功能:一个带有一个参数,另一个带有n个参数。第一个用作基本情况,后者用作递归情况 所以,如果你这样做:
has<bool,int,char,float>();
跟踪是:
致电
has<bool,int,char,float>()
(致递归案件)
致电has<bool,int,char>()
(呼吁递归案件)
致电has<bool,int>()
(呼吁递归案件)
致电has<bool>()
(调用基本案例)
注意:当然这个示例不起作用,因为我在示例中使用的类型没有::tag
成员。它只是呼叫追踪的一个例子。
另外,我已经将跟踪简化为不会使示例过于复杂。真正的痕迹是:
致电
has<bool,int,char,float>()
(致递归案件)
....致电has<bool>()
(调用基础案例)//左右&amp;&amp;
....致电has<int,char,float>()
(呼吁递归案件)//&amp;&amp;
的右侧 ........拨打has<int>()
(呼叫基本情况)//左侧&amp;&amp;
........拨打has<char,float>()
(呼叫递归案例)//&amp;&amp;&amp;的右侧 ............拨打has<char>()
(拨打基本案例)//&amp;&amp;
左侧 ............拨打has<float>()
(呼叫基本情况)//右侧&amp;&amp;
答案 1 :(得分:2)
您可以使用std::min
:
#include<algorithm>
template <typename... Args>
bool hasz()
{
return std::min({has<Args>()...});
}
请注意,这没有短路行为 - 它将始终为所有参数评估has<Args>
。如果是问题,那就使用递归版本。