使用函数模板参数作为类模板参数?

Use function template argument as class template argument?

本文关键字:参数 函数模板      更新时间:2023-10-16

我试图通过实现类似于 C# 的 Linq 的东西来熟悉 C++ 中的模板。最后,查询数据应如下所示

SomeIteratorType begin = /* ... */;
SomeIteratorType end = /* ... */;
typedef iterator_traits<SomeIteratorType>::value_type Type;
linq<int> query = linq<Type>(begin, end)
.where([](Type value) -> bool { return /* ... */; })
.select([](Type value) -> int { return value.some_property; });
for (int value : query)
cout << value << endl;

我从

template<typename Type>
class linq : public std::iterator<std::input_iterator_tag, Type> {
public:
typedef bool (WherePredicate)(Type value);
// ...
// Copy-constructor, operator=, operator++, ...
// ...
// ...
// Linq functions, e.g.
linq& where (WherePredicate& predicate) const; // returns some specialization of the linq-class (should probably not name this "where")
// ...
};

但是如何从示例中声明构造函数linq(begin, end)呢?如果beginend是类型IteratorType我需要生成的linq对象是类型linq<std::iterator_traits<IteratorType>::value_type>。甚至有可能从函数模板参数中计算出类模板参数吗?如果不是,当像linq<Type>(begin, end)一样使用时,是否至少可以确保IteratorType beginIteratorType end足够std::iterator_traits<IteratorType>::value_type == Type

因此,C# 通过接口使用堆分配的对象和间接寻址,就好像它是空闲的一样。

如果你想效仿它,你必须做同样的事情。 如果你还需要值语义,你必须编写包含智能指针并表现得像值的包装器。

另一种方法是不键入 erase;相反,linq 对象是每个修饰符链的唯一类型。 这里linq是一个函数而不是一个 tyoe,您将返回值存储在auto变量中。

这两种方法可以一起工作,如lambda(无类型可调用对象(和std函数(值类型,可以在构造时堆分配和类型擦除,以忘记可调用对象以外的所有调用接口(。

为了更进一步,请了解类型擦除(包括如何编写 std 函数(、C++中的常规类型,并可能查看 Rangesv3 一个支持类似 linq 的流表达式的库。