This is my current program:
#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;
template<class Feature, class ...FeatureList>
static constexpr bool isConfiguredWith() {
return has_feature_v<Feature, FeatureList...>;
}
struct CanWalk {
};
struct CanNotWalk {
};
template<class... FeatureList>
struct Robot {
static auto configure() {
return Robot<WalkFeature < FeatureList...>>
();
}
private:
template<typename ...Config>
using WalkFeature =
std::conditional_t<isConfiguredWith<CanWalk, Config...>(), CanWalk, CanNotWalk>;
};
int main() {
Robot<CanWalk> robot_A = Robot<CanWalk>::configure();
Robot<CanNotWalk> robot_B = Robot<>::configure();
return 0;
}
Basically, Robot is a struct that can be configured with many other struct (they are used as token here), then Robot<T...>::configure() trim and organize the template parameters passed into to Robot. In the end we have:
Robot<CanWalk> robot_A = Robot<CanWalk, CanWalk>::configure();
Robot<CanNotWalk> robot_B = Robot<>::configure();
Although duplicated features CanWalk are passed into as template parameters, they are all deleted when constructing Robot via function configure().
This is working well until I add a template parameter to feature CanWalk:
template <int Speed>
struct CanWalk {
};
Now everything breaks since CanWalk is no longer a legit type, it needs a template parameter.
For error error: use of class template 'CanWalk' requires template arguments occured from:
template<typename ...Config>
using WalkFeature =
std::conditional_t<isConfiguredWith<CanWalk>(), CanWalk, CanNotWalk>;
How do I fix it?
How can I define them as:
Robot<CanWalk<5>> robot_A = Robot<CanWalk<5>>::configure();
Robot<CanNotWalk> robot_B = Robot<>::configure();
?
live code: https://godbolt.org/z/4K9TxohWq