我试图通过实现类似于 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)
从例子?如果begin
和 end
类型为 IteratorType
我需要结果 linq
对象类型为 linq<std::iterator_traits<IteratorType>::value_type>
.甚至可以从函数模板参数中计算出类模板参数吗?如果不是,是否至少可以确保 IteratorType begin
和 IteratorType end
够了std::iterator_traits<IteratorType>::value_type == Type
, 当像 linq<Type>(begin, end)
那样使用时?
最佳答案
因此 C# 使用堆分配的对象和通过接口(interface)的间接寻址,就好像它是免费的。
如果你想模仿它,你也必须这样做。如果您还需要值语义,则必须编写包含智能指针并表现得像值的包装器。
另一种方法是不键入删除;相反,linq 对象是每个修饰符链的唯一类型。这里 linq
是一个函数而不是一个 tyoe,您将返回值存储在 auto
变量中。
这两种方法可以一起工作,例如 lambda(没有类型错误的可调用对象)和 std 函数(可以在构造时堆分配和类型删除的值类型,以忘记除了可调用对象的调用接口(interface)之外的所有内容)。
要进一步了解类型删除(包括如何编写 std 函数)、C++ 中的常规类型,并可能查看 Rangesv3 库,该库支持类似 linq 的流式表达式。
关于c++ - 使用函数模板参数作为类模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50434766/