将lambda传递给模板类中的方法(头文件/源文件问题)

C++ Pass lambda to a method in template class (header/source files issue)

本文关键字:方法 文件 问题 源文件 lambda      更新时间:2023-10-16

我在传递lambda表达式作为模板类方法的参数时遇到问题。

如果我编译以下代码:

main.cpp:

#include "a.h"
int main(int argc, char** argv) {
    A<int> o;
    o.a([&](){  });
}

a.h:

template <typename T>
class A {
public:
    template <typename Lambda>
    void a(const Lambda& f) {
        f();
    }
};

工作正常

然而,我不想在a.h中实现类A,我想把代码放在单独的cpp文件中。现在我有了

main.cpp:

不变

a.h:

template <typename T>
class A {
public:
    template <typename Lambda>
    void a(const Lambda& f);
};

a.cpp:

#include "a.h"
template <typename T>
template <typename Lambda>
void A<T>::a(const Lambda& f) {
    f();
}

template class A<int>;

我现在得到以下错误:

In file included from test.cpp:1:0:
a.h:7:7: error: 'void A<T>::a(const Lambda&) [with Lambda = main(int, char**)::__lambda0; T = int]', declared using local type 'const main(int, char**)::__lambda0', is used but never defined [-fpermissive]
  void a(const Lambda& f);
       ^

为什么?我该怎么修理它?

我注意到,如果我把所有的东西都放在同一个cpp文件,它工作。这个问题只发生在我想这样分割它的时候,这是保持我的代码有条理所必需的。

谢谢你的回答

这很奇怪,因为即使这样也能工作:

main.cpp

#include "a.h"
int main(int argc, char** argv) {
    A<int> o;
    o.a([&](){  });
}
template <typename T>
template <typename Lambda>
void A<T>::a(const Lambda& f) {
    f();
}
template class A<int>;

a.h

template <typename T>
class A {
public:
    template <typename Lambda>
    void a(const Lambda& f);
};

这工作。出于某种原因,当我在两个不同的cpp文件中分离main()和方法实现时,它将不起作用。

为什么?

好的,我想我找到一个解释了。

当你将模板类的代码拆分为。h和。cpp时,你需要使模板实例化显式。

问题是lambda表达式没有指定的类型,因此不可能为lambda类型编写该函数的模板显式实例。

我想要的是不可能的是否有可能显式特化模板以匹配lambda?

一般来说,你不能真正把模板函数/类的实现放在。cpp文件中。原因是,当.cpp文件单独编译时,编译器无法知道将向其传递哪些模板参数。因此,我认为根据您的情况,最好将所有内容留在头文件中。

正如其他人所说,不可能将模板类与其头文件和cpp文件中的实现分开。但是,如果类本身不是模板,而是其中一个成员函数接受lambda,则可以分离实现。要做到这一点,不要使用template来声明lambda。使用std::function代替。

头文件a.h .

#include <functional>
namespace xx {
  struct A {
    void square(int num, std::function<void(int)>consumer);
  };
}

CPP文件a.cpp .

namespace xx {
  void A::square(int num, std::function<void(int)>consumer) {
    consumer(num * num);
  }
}

按如下方式使用

#include "a.h"
#include <assert.h>
int main() {
  xx::A a;
    
  a.square(10, [](int result) {
      assert(result == 100);
  });
    
  return 0;
}