仅当类型包包含 C++ 中的特定类型时才向类添加方法

问题描述 投票:0回答:1

我正在尝试创建一个可以包含类型包的类。

// 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()
。我可能误解了它是如何运作的。

我找到了一些有些相关的答案,但没有一个答案能够根据我的需要正确组合因素。

这个功能有可能实现吗?如果是的话,怎么办?

c++ c++17 template-meta-programming
1个回答
0
投票

这个功能有可能实现吗?如果是的话,怎么办?

是的,这是可能的。最小的改变解决方案是没有

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_);
}

观看现场演示

© www.soinside.com 2019 - 2024. All rights reserved.