C++模板参数:在编译时查找参数是否存在于参数列表中
C++ template parameter: to find out if a parameter exists in parameter list during compilation time
我有一个结构 Robot
:
template<typename... FeatureList>
struct Robot {
Robot() = default;
};
它可以配置一些功能(这里使用一些结构作为令牌):
struct CanWalk {
};
struct CanNotWalk {
};
struct CanFly {
};
struct CanNotFly {
};
Robot<CanWalk, CanFly> robot_A = Robot<CanWalk, CanFly>();
然后我不知道如何在结构 Robot
中实现 bool 函数 isConfiguredWith()
来告诉我功能是否被编码到结构中:
template<typename... FeatureList>
template<typename Feature>
constexpr bool Robot<FeatureList...>::isConfiguredWith() {
// how do I implement it?
return false;
}
int main() {
Robot<CanWalk, CanFly> robot_A = Robot<CanWalk, CanFly>();
static_assert(robot_A.isConfiguredWith<CanWalk>());
static_assert(robot_A.isConfiguredWith<CanFly>());
return 0;
}
如何遍历 FeatureList
以找出 Feature
是否存在于列表中,在编译时间?
完整代码:
struct CanWalk {
};
struct CanNotWalk {
};
struct CanFly {
};
struct CanNotFly {
};
template<typename... FeatureList>
struct Robot {
Robot() = default;
template<typename Feature>
constexpr bool isConfiguredWith();
};
template<typename... FeatureList>
template<typename Feature>
constexpr bool Robot<FeatureList...>::isConfiguredWith() {
return false;
}
int main() {
Robot<CanWalk, CanFly> robot_A = Robot<CanWalk, CanFly>();
static_assert(robot_A.isConfiguredWith<CanWalk>());
static_assert(robot_A.isConfiguredWith<CanFly>());
return 0;
}
你可以这样写一个特征:
#include <type_traits>
#include <iostream>
template<typename... FeatureList>
struct Robot {
Robot() = default;
};
struct CanWalk {};
struct CanNotWalk {};
struct CanFly {};
struct CanNotFly {};
template <typename Feature,typename... Features>
using has_feature_impl = std::integral_constant<bool,(std::is_same_v<Feature,Features> || ...)>;
template <typename Feature,typename T> struct has_feature;
template <typename Feature,typename... Features> struct has_feature<Feature,Robot<Features...>> : has_feature_impl<Feature,Features...> {};
int main()
{
using R1 = Robot<CanWalk,CanFly>;
std::cout << has_feature<CanWalk,R1>::value;
std::cout << has_feature<CanNotFly,R1>::value;
}
10
您可以添加功能测试类型特征:
#include <type_traits>
template<class Feature, class... FeatureList>
struct has_feature {
static constexpr bool value = (std::is_same_v<Feature, FeatureList> || ...);
};
template<class Feature, class... FeatureList>
inline constexpr bool has_feature_v = has_feature<Feature,FeatureList...>::value;
然后像这样在 Robot
class 中使用它:
template<class... FeatureList>
struct Robot {
Robot() = default;
template<class Feature>
static constexpr bool isConfiguredWith() {
return has_feature_v<Feature,FeatureList...>;
}
};
(std::is_same_v<Feature, FeatureList> || ...)
是 fold expression.
假设 FeatureList...
是 CanWalk, CanFly
。上面的折叠表达式然后“展开”为:
std::is_same_v<Feature, CanWalk> || std::is_same_v<Feature, CanFly>
您还可以在 cppinsights.io
中更详细地研究这些模板实例化
我有一个结构 Robot
:
template<typename... FeatureList>
struct Robot {
Robot() = default;
};
它可以配置一些功能(这里使用一些结构作为令牌):
struct CanWalk {
};
struct CanNotWalk {
};
struct CanFly {
};
struct CanNotFly {
};
Robot<CanWalk, CanFly> robot_A = Robot<CanWalk, CanFly>();
然后我不知道如何在结构 Robot
中实现 bool 函数 isConfiguredWith()
来告诉我功能是否被编码到结构中:
template<typename... FeatureList>
template<typename Feature>
constexpr bool Robot<FeatureList...>::isConfiguredWith() {
// how do I implement it?
return false;
}
int main() {
Robot<CanWalk, CanFly> robot_A = Robot<CanWalk, CanFly>();
static_assert(robot_A.isConfiguredWith<CanWalk>());
static_assert(robot_A.isConfiguredWith<CanFly>());
return 0;
}
如何遍历 FeatureList
以找出 Feature
是否存在于列表中,在编译时间?
完整代码:
struct CanWalk {
};
struct CanNotWalk {
};
struct CanFly {
};
struct CanNotFly {
};
template<typename... FeatureList>
struct Robot {
Robot() = default;
template<typename Feature>
constexpr bool isConfiguredWith();
};
template<typename... FeatureList>
template<typename Feature>
constexpr bool Robot<FeatureList...>::isConfiguredWith() {
return false;
}
int main() {
Robot<CanWalk, CanFly> robot_A = Robot<CanWalk, CanFly>();
static_assert(robot_A.isConfiguredWith<CanWalk>());
static_assert(robot_A.isConfiguredWith<CanFly>());
return 0;
}
你可以这样写一个特征:
#include <type_traits>
#include <iostream>
template<typename... FeatureList>
struct Robot {
Robot() = default;
};
struct CanWalk {};
struct CanNotWalk {};
struct CanFly {};
struct CanNotFly {};
template <typename Feature,typename... Features>
using has_feature_impl = std::integral_constant<bool,(std::is_same_v<Feature,Features> || ...)>;
template <typename Feature,typename T> struct has_feature;
template <typename Feature,typename... Features> struct has_feature<Feature,Robot<Features...>> : has_feature_impl<Feature,Features...> {};
int main()
{
using R1 = Robot<CanWalk,CanFly>;
std::cout << has_feature<CanWalk,R1>::value;
std::cout << has_feature<CanNotFly,R1>::value;
}
10
您可以添加功能测试类型特征:
#include <type_traits>
template<class Feature, class... FeatureList>
struct has_feature {
static constexpr bool value = (std::is_same_v<Feature, FeatureList> || ...);
};
template<class Feature, class... FeatureList>
inline constexpr bool has_feature_v = has_feature<Feature,FeatureList...>::value;
然后像这样在 Robot
class 中使用它:
template<class... FeatureList>
struct Robot {
Robot() = default;
template<class Feature>
static constexpr bool isConfiguredWith() {
return has_feature_v<Feature,FeatureList...>;
}
};
(std::is_same_v<Feature, FeatureList> || ...)
是 fold expression.
假设 FeatureList...
是 CanWalk, CanFly
。上面的折叠表达式然后“展开”为:
std::is_same_v<Feature, CanWalk> || std::is_same_v<Feature, CanFly>
您还可以在 cppinsights.io
中更详细地研究这些模板实例化