【发布时间】:2021-12-28 17:13:25
【问题描述】:
我有一堆实现通用调用运算符的类:
template<typename T = char>
struct match {
template<initer_of_type<T> IterT>
constexpr auto operator()(IterT iter) const -> std::optional<decltype(iter)> {
// ... function body
}
// ... some members
}
// ... more similar structs
在类模板中,运算符本身也是一个模板。
注意:我在这里使用的概念是我接受任何返回特定值类型的输入迭代器:
template<typename IterT, typename T>
concept initer_of_type =
std::input_iterator<IterT>
&& std::is_same_v<typename IterT::value_type, T>;
这样我就可以在任何可迭代的Ts 容器上使用该算法...
我希望能够保存这些对象的数组,所有这些对象都具有相同的模板参数T,但可能是不同的类。似乎我既不能使用普通继承也不能使用类型擦除(至少我知道的方式),因为该函数是一个模板。有没有好的方法来做到这一点?还是我在寻找错误的解决方案?
【问题讨论】:
-
数组中可能的类型是否有界?
-
std::variant 也许?
-
@Klaus 我觉得应该有更好的方法来做到这一点。使用变体,我必须在任何给定时刻检查包含哪种类型,然后将
std::get排除在变体之外,这对于用户 POV 来说既不方便,又比简单地使用继承产生更大的运行时开销(如果可能的话)。 -
"这对于用户 POV 来说非常不方便,并且比简单地使用继承(如果可能的话)产生更大的运行时开销。"没有运行时开销。
-
这个问题有一些相似的感觉:stackoverflow.com/questions/70002943/…。我在那里写了一个初步的
any_const_input_iterator_of<T>,它可能被用作这些类的常规类型擦除接口中的函数调用运算符的参数。但是,如果您的仿函数类集是预先知道的,那么我肯定会采用variant<match<T>, other_match<T>, third_match<T>>的方法来处理您所有的match类类。您还可以将变体隐藏在内部visits 的便捷界面后面。
标签: c++ templates c++20 type-erasure