【问题标题】:c++ template member function instantiation when using lambdas使用 lambdas 时的 c++ 模板成员函数实例化
【发布时间】:2021-10-26 12:06:18
【问题描述】:

下面的一小段代码编译并运行

#include <iostream>
using namespace std;
template<class T>
class A {
public:
    template<class T2>
    void f(T2 a);
};
template<class T>
template<typename T2>
void A<T>::f(T2 a){a();}
int main()
{
    A<int> ac;
    ac.f([](){cout<<"bla"<<endl;});
}

但是当分割成文件时 hpp:

template<class T>
class A {
public:
    template<class T2>
    void f(T2 a);
};

cpp:

#include "a.hpp"
#include <iostream>
using namespace std;
template<class T>
template<typename T2>
void A<T>::f(T2 a){a();}

和主要的:

#include "a.hpp"
#include <iostream>
using namespace std;
int main()
{
    A<int> ac;
    ac.f([](){cout<<"bla"<<endl;});
}

我得到一个编译时错误:

In file included from main.cpp:1:
a.hpp:5:10: error: ‘void A<T>::f(T2) [with T2 = main()::<lambda()>; T = int]’, declared using local type ‘main()::<lambda()>’, is used but never defined [-fpermissive]
    5 |     void f(T2 a);
      |          ^
a.hpp:5:10: warning: ‘void A<T>::f(T2) [with T2 = main()::<lambda()>; T = int]’ used but never defined
/usr/bin/ld: cannot find main.o: No such file or directory
collect2: error: ld returned 1 exit status

我假设我需要在cpp文件中实例化模板,例如。

template void A<int>::f<>();

但到目前为止,我还未能正确使用语法。由于 main 中“f”的函数参数作为 lambda,我想知道这是否可能。

非常感谢任何建议。

【问题讨论】:

  • 有两个模板,类和函数。我假设您需要显式地实例化两者才能使其正常工作,但由于该函数是使用来自另一个 TU 的 lambda 调用的,因此您无法显式地实例化它。通常,您将实现保留在模板的标题中。
  • 嗨。谢谢。但是,将所有内容保留在标题中可以规避问题,但不能解决问题。
  • 将所有内容保留在标题中是惯用的方法。但是,如果您绝对不希望这样,则必须放弃使用 lambda,因为它们的类型对于每个 lambda 都是唯一的,并且由编译器生成。 AFAIK 无法明确指定 lambda 的类型。

标签: c++ templates lambda template-meta-programming


【解决方案1】:

每个 lambda 都有自己独特的类型,并且它不能出现在未计算的上下文中(至少在 C++20 之前),其中包括函数模板参数。你可以这样做:

void A<int>::f<std::function<void()>>();

以实例化一个函数对象为代价,或者将代码一起移动,就像在您的第一个示例中一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    相关资源
    最近更新 更多