【问题标题】:Using generic lambda of header file in implementation file在实现文件中使用头文件的通用 lambda
【发布时间】:2020-02-14 11:25:50
【问题描述】:

我在标题MyType.hpp中有这种类型:

struct MyType
{
    template<typename T>
    void operator(T t)
    {
        auto lamdba = [t](auto i){ t.someCall(i); };
        someMethod(lamdba);
    }

    template<typename L>
    void someMethod(L);
};

因此,someMethod 使用接受泛型参数的泛型 lambda 调用。 是否有可能在MyType.cpp 中为someMethod 提供一个实现? 这不起作用:

template<typename L>
void MyType::someMethod(L lambda)
{
    lambda(42);
    lambda("42");
    // etc...
}

由于不允许部分特化(仅对函数模板进行完全特化),有没有其他方法可以将头文件的 lambda “传递”到实现文件MyType.cpp? 如果无法传递,也许有一种方法可以将这个 lambda 动态存储在 MyType.hpp 中并在 MyType.cpp 中访问它?

【问题讨论】:

  • 模板必须在标头中定义(非正式地说)。
  • 即使在single source 中也无法编译。请提供 minimal reproducible example 头文件中的所有内容,然后询问如何将内容移动到 cpp。
  • @MarekR:你错误地喂了洞Demo(缺少const)。
  • @Jarod42 是的,你说得对,但是有 more then one way to fix it 并且 OP 应该首先定义他到底需要什么。
  • 是的,一般来说模板应该在headers中定义,但在极端情况下有一些技巧,模板可以限制为特定类型,一些模板方法可以移动到cpp。

标签: c++ templates lambda template-specialization generic-lambda


【解决方案1】:

每个 lambda 都有自己的类型。无论如何,您将无法在源代码中记下类型。

由于具有模板定义的翻译单元永远不会看到 lambda 类型,因此模板永远不会被实例化。而且您将无法获得 lambda 的类型以使其成为特化,也无法将其用于手动实例化。

因此答案是:如果模板仅在其自己的翻译单元中可见,则不能将 lambda 闭包用作专用模板或手动实例化的模板的参数。

【讨论】:

    【解决方案2】:
    template<typename L>
    void MyType::someMethod(L lambda)
    {
        lambda(42);
        lambda("42");
        // etc...
    }
    

    不会工作。 实例化时,必须完整定义模板(和 lambda)。 .cpp 中不能有通用模板定义 - 只有完整的专业化可以在 .cpp 中实现(非正式地说)。有多种方法可以解决这个问题。蛮力方法是为每种类型添加特化(可能调用仅存在于 .cpp 中的通用模板)。另一种方法可能是使用某种抽象工厂设计(根据分派类型返回接口) - 但这里的信息太少,这是一个可行的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 2016-04-15
      • 1970-01-01
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多