我正在尝试创建一个可以包含类型包的类。
// Pack.hpp
template <typename... Types>
class Pack final {
Pack(const std::tuple<Types...> items) : items_(std::move(items)){};
std::tuple<Types...> items_;
};
但我希望
Pack
公开一些基于其中的Types
的方法。例如,我想这样做:
// Consumer.cpp
Person person { ... };
Car car { ... };
Pack<Person, Car> personAndCarPack { { person, car } };
Pack<Person> personPack { { person } };
// Ok
personAndCarPack.getCar();
// Ok
personAndCarPack.getPerson();
// Ok
personPack.getPerson();
// Shouldn't compile - getCar() shouldn't exist!
personPack.getCar();
我假设我必须或多或少这样声明它:
// Pack.hpp
template <typename... Types>
class Pack final {
Pack(const std::tuple<Types...> items) : items_(std::move(items)){};
std::tuple<Types...> items_;
Car getCar() {
return std::get<Car>(items_);
}
Person getPerson() {
return std::get<Person>(items_);
}
};
但是当然,无论类型如何,都会公开
Pack
中的方法。
我得到的最接近的是:
...
typename std::enable_if<(std::is_same_v<Types, Car> && ...), Car>::type
getCar() {
return std::get<Car>(items_);
}
...
但它无法编译;我在
'enable_if' cannot be used to disable this declaration
电话中接到 std::is_same_v()
。我可能误解了它是如何运作的。
我找到了一些有些相关的答案,但没有一个答案能够根据我的需要正确组合因素。
这个功能有可能实现吗?如果是的话,怎么办?
这个功能有可能实现吗?如果是的话,怎么办?
是的,这是可能的。最小的改变解决方案是没有
std::enable_if
/ SFINAE。
// Method to get a Car from the Pack (enabled only if Car is in Types...)
template <typename T = Car>
constexpr auto getCar() -> decltype(std::get<Car>(items_))
{
return std::get<Car>(items_);
}
// Method to get a Person from the Pack (enabled only if Person is in Types...)
template <typename T = Person>
constexpr auto getPerson() -> decltype(std::get<Person>(items_))
{
return std::get<Person>(items_);
}