【发布时间】:2018-07-19 16:38:32
【问题描述】:
我有一个类Derived,它继承自类Base<ResourceType>:
template <class ResourceType>
class Base {
protected:
ResourceType* resource;
public:
void set_resource(ResourceType* resource) {
this->resource = resource;
}
};
template <class ResourceType>
class Derived : public Base<ResourceType> {
public:
using Base<ResourceType>::resource;
void print () {
std::cout << *resource << std::endl;
}
};
我想创建一个工厂来创建Derived 类型的对象。我当然可以用函数来做到这一点:
template <typename ResourceType>
auto derived_factory () {
return new Derived<ResourceType>();
}
auto derived = *(derived_factory<int>());
但是,我无法为工厂编写 lambda 函数。如果我使用 auto 关键字接受模板参数,我可以编写模板化的 lambda 函数,但在这里我只想使用模板来确定返回类型。以下失败:
auto derived_factory = []<typename ResourceType>() {
return new Derived<ResourceType>();
};
auto derived = *(derived_factory<int>());
出现错误:
inherit_unknown_type.cpp: In function ‘int main()’:
inherit_unknown_type.cpp:27:36: error: expected primary-expression before ‘int’
auto derived = *(derived_factory<int>());
^~~
inherit_unknown_type.cpp:27:36: error: expected ‘)’ before ‘int’
我只是错误地调用了 lambda 吗?还是要等C++20?
【问题讨论】:
-
我猜你可以使用一个幻像类型的虚拟参数,但你为什么首先想要一个 lambda?
-
我猜与人们为什么更喜欢 lambda 而不是函数的原因相同。我们在其他地方使用了lambda,所以会和代码保持一致。
-
我不知道为什么有人会不加选择地偏爱 lambdas。如果你给它一个名字并且没有捕获,它也可以是一个常规函数。
-
我猜你说得有道理。为了给你更多的上下文,我们的库提供了一个类,它的对象使用用户提供的工厂函数创建用户定义类的对象。这些工厂函数仅用于提供给我们库类的构造函数。而且 C++ 不支持嵌套函数。对于用户来说,编写 lambdas 而不是函数可以说更整洁,因为他们可以在构造函数调用中内联 lambdas。用户编写他们不调用自己的函数,而只是传递给构造函数并不理想。
-
好的,如果函数是用户的代码,那么没有理由不允许它成为 lambda。如果 C++20 不是一个选项,我会使用标签调度(我在上面的评论中将其称为幻像类型)。
标签: c++ templates lambda c++17 generic-lambda