简体   繁体   English

C ++ 17中没有自动参数的模板化lambda

[英]Templated lambdas in C++17 without an auto argument

I have a class Derived that inherits from class Base<ResourceType> : 我有一个继承自Base<ResourceType>类的Derived类:

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

I want to create a factory that creates objects of type Derived . 我想创建一个创建Derived类型对象的工厂。 I can of course do this with functions: 我当然可以用功能做到这一点:

template <typename ResourceType>
auto derived_factory () { 
  return new Derived<ResourceType>(); 
}

auto derived = *(derived_factory<int>());

But, I am not able to write a lambda function for the factory. 但是,我无法为工厂编写lambda函数。 I can write templated lambda functions if I was accepting a template argument using the auto keyword, but here I just want to use the template to determine the return type. 如果我使用auto关键字接受模板参数,我可以编写模板化的lambda函数,但在这里我只想使用模板来确定返回类型。 The following fails: 以下失败:

auto derived_factory = []<typename ResourceType>() {
  return new Derived<ResourceType>();
};

auto derived = *(derived_factory<int>());

with the error: 有错误:

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’

Am I just calling the lambda incorrectly? 我只是错误地调用了lambda吗? Or do I have to wait for C++20 ? 或者我必须等待C++20

Template parameter lists in lambda expressions is a C++20 feature . lambda表达式中的模板参数列表是C ++ 20的一个特性

(In fact, my GCC says that in the diagnostic: error: lambda templates are only available with -std=c++2a or -std=gnu++2a [-Wpedantic] ) (事实上​​,我的GCC在诊断中说: error: lambda templates are only available with -std=c++2a or -std=gnu++2a [-Wpedantic]

But you don't have to wait for C++20, it's already supported by GCC 8 with -std=c++2a flag. 但是你不必等待C ++ 20,它已经被GCC 8 支持 -std=c++2a标志。

And you'll have to change the call syntax: Instead of derived_factory<int>() , you need derived_factory.operator()<int>() . 而且你必须改变调用语法:而不是derived_factory<int>() ,你需要derived_factory.operator()<int>()


As an alternative (if you don't want a free function), I suggest using a variation of tag dispatch: 作为替代方案(如果您不想要免费功能),我建议使用标签调度的变体:

auto derived_factory = [](auto tag) {
    return new Derived<typename tag::type>();
};

template <typename T> struct tag_type {using type = T;};

// Usage:
derived_factory(tag_type<int>{})

Also, even if you make it compile somehow, this line: 此外,即使你以某种方式编译它,这一行:

auto derived = *(derived_factory<int>());

will cause a memory leak no matter what. 无论如何都会导致内存泄漏。 To avoid that, you should store the result as a pointer or a reference. 为避免这种情况,您应将结果存储为指针或引用。 Or even better, use a smart pointer. 或者甚至更好,使用智能指针。

Waiting for C++20, you can return the lambda from a template class 等待C ++ 20,您可以从模板类返回lambda

template <typename ResourceType>
auto make_derived_factory ()
 { return []{ return new Derived<ResourceType>{}; }; }

auto derived = make_derived_factory<int>();

int main ()
 {
   auto df { derived() };
 }

The above doesn't work, but this does: 以上不起作用,但这样做:

auto derived_factory = [](auto tag) 
{
    return new Derived<decltype(tag)::type>();
};

template <typename T> struct tag_type {using type = T;};

// Usage:
derived_factory(tag_type<int>{})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++ 17使用模板参数推导指南继承lambdas集 - C++17 Inheriting set of lambdas with template argument deduction guides 通用(多态)lambda的C ++ 17矢量 - C++17 vector of Generic (Polymorphic) lambdas C++17 - 可变参数模板 arguments - 使用模板参数调用 class 方法返回值 - C++17 - variadic template arguments - call class method on return value from previous with templated argument 在没有 lambda 的情况下将模板化函数作为方法参数传递? - Passing a templated function as method argument without lambdas? C++17 模板参数推导失败 - C++17 Template argument deduction failed C++17中模板参数中auto的优点 - Advantages of auto in template parameters in C++17 如何在 c++17 中使用嵌套的 static 模板结构 - How to use Nested static templated structs in c++17 C++17 中的“如果 constexpr”在非模板 function 中不起作用 - "If constexpr" in C++17 does not work in a non-templated function C++17 默认模板参数:无效使用没有参数列表的模板名称 - C++17 Default template arguments: invalid use of template-name without an argument list C++17 将对模板化 class 接口的引用传递给兄弟模板化 class 构造函数 - C++17 Pass reference to interface of templated class into sibling templated class constructor
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM