为什么以下代码无法编译(C++ lambda 问题)
Why does the following code failed to compile (C++ lambda problem)
好吧,我正在编写一个函数,其中我在 C++ (GNU C++14) 中使用了递归 lambda。所以我尝试了 y_combinator
方法,从 main()
函数之外的声明开始(我之前使用过 using namespace std;
)。
#include <bits/stdc++.h>
using namespace std;
template<class Fun>
class y_combinator_result {
Fun fun_;
public:
template<class T>
explicit y_combinator_result(T &&fun): fun_(forward<T>(fun)) {}
template<class ...Args>
decltype(auto) operator()(Args &&...args) {
return fun_(ref(*this), forward<Args>(args)...);
}
};
template<class Fun>
decltype(auto) y_combinator(Fun &&fun) {
return y_combinator_result<decay_t<Fun>>(forward<Fun>(fun));
}
int main () {
cin.tie(0)->sync_with_stdio(0);
int N; cin >> N;
vector<int> adj[N+1];
for (int i = 0; i < N-1; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
vector<int> d(N+1);
auto dfs = y_combinator([&](auto dfs, int u, int p, int &r) {
if (u == p) d[u] = 0;
if (d[u] > d[r]) r = u;
for (auto &v : adj[u]) {
if (v != p) {
d[v] = d[u]+1;
dfs(v, u, r);
}
}
});
}
现在我有一个简单易懂的问题要问你们:是什么导致这个 lambda 函数甚至无法编译(这发生在 main 函数内部)?
问题是,当我尝试编译它时,我收到了这条灾难性的消息:
test1.cpp: In function 'int main()':
test1.cpp:36:29: error: use of deleted function 'main()::<lambda(auto:1, int, int, int&)>::~<lambda>()'
36 | auto dfs = y_combinator([&](auto dfs, int u, int p, int &r) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 | if (u == p) d[u] = 0;
| ~~~~~~~~~~~~~~~~~~~~~
38 | if (d[u] > d[r]) r = u;
| ~~~~~~~~~~~~~~~~~~~~~~~
39 | for (auto &v : adj[u]) {
| ~~~~~~~~~~~~~~~~~~~~~~~~
40 | if (v != p) {
| ~~~~~~~~~~~~~
41 | d[v] = d[u]+1;
| ~~~~~~~~~~~~~~
42 | dfs(v, u, r);
| ~~~~~~~~~~~~~
43 | }
| ~
44 | }
| ~
45 | });
| ~
test1.cpp:36:31: note: 'main()::<lambda(auto:1, int, int, int&)>::~<lambda>()' is implicitly deleted because the default definition would be ill-formed:
36 | auto dfs = y_combinator([&](auto dfs, int u, int p, int &r) {
| ^
所以我通过捕获 2 个矢量名称 d
和 adj
来尝试一个小修复
#include <bits/stdc++.h>
using namespace std;
template<class Fun>
class y_combinator_result {
Fun fun_;
public:
template<class T>
explicit y_combinator_result(T &&fun): fun_(forward<T>(fun)) {}
template<class ...Args>
decltype(auto) operator()(Args &&...args) {
return fun_(ref(*this), forward<Args>(args)...);
}
};
template<class Fun>
decltype(auto) y_combinator(Fun &&fun) {
return y_combinator_result<decay_t<Fun>>(forward<Fun>(fun));
}
int main () {
cin.tie(0)->sync_with_stdio(0);
int N; cin >> N;
vector<int> adj[N+1];
for (int i = 0; i < N-1; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
vector<int> d(N+1);
auto dfs = y_combinator([&d, &adj](auto dfs, int u, int p, int &r) { // I changed this line
if (u == p) d[u] = 0;
if (d[u] > d[r]) r = u;
for (auto &v : adj[u]) {
if (v != p) {
d[v] = d[u]+1;
dfs(v, u, r);
}
}
});
}
并且程序按预期编译...
从我的角度来看,显然有一个非常大的问题:为什么我使用 [&]
捕获 main()
函数内部所有内容的第一段代码失败,但第二段代码有效?有什么办法解决这个问题,因为我不想花时间捕获变量...
P/s : 请原谅我的英语不好。我不是母语人士。
C++ 没有 VLA vector<int> adj[N+1];
。使用此 VLA 会导致编译器错误。参见 。
使 vector<int> adj[N+1];
-> vector<vector<int>> adj(N+1);
使示例符合要求。
好吧,我正在编写一个函数,其中我在 C++ (GNU C++14) 中使用了递归 lambda。所以我尝试了 y_combinator
方法,从 main()
函数之外的声明开始(我之前使用过 using namespace std;
)。
#include <bits/stdc++.h>
using namespace std;
template<class Fun>
class y_combinator_result {
Fun fun_;
public:
template<class T>
explicit y_combinator_result(T &&fun): fun_(forward<T>(fun)) {}
template<class ...Args>
decltype(auto) operator()(Args &&...args) {
return fun_(ref(*this), forward<Args>(args)...);
}
};
template<class Fun>
decltype(auto) y_combinator(Fun &&fun) {
return y_combinator_result<decay_t<Fun>>(forward<Fun>(fun));
}
int main () {
cin.tie(0)->sync_with_stdio(0);
int N; cin >> N;
vector<int> adj[N+1];
for (int i = 0; i < N-1; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
vector<int> d(N+1);
auto dfs = y_combinator([&](auto dfs, int u, int p, int &r) {
if (u == p) d[u] = 0;
if (d[u] > d[r]) r = u;
for (auto &v : adj[u]) {
if (v != p) {
d[v] = d[u]+1;
dfs(v, u, r);
}
}
});
}
现在我有一个简单易懂的问题要问你们:是什么导致这个 lambda 函数甚至无法编译(这发生在 main 函数内部)?
问题是,当我尝试编译它时,我收到了这条灾难性的消息:
test1.cpp: In function 'int main()':
test1.cpp:36:29: error: use of deleted function 'main()::<lambda(auto:1, int, int, int&)>::~<lambda>()'
36 | auto dfs = y_combinator([&](auto dfs, int u, int p, int &r) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 | if (u == p) d[u] = 0;
| ~~~~~~~~~~~~~~~~~~~~~
38 | if (d[u] > d[r]) r = u;
| ~~~~~~~~~~~~~~~~~~~~~~~
39 | for (auto &v : adj[u]) {
| ~~~~~~~~~~~~~~~~~~~~~~~~
40 | if (v != p) {
| ~~~~~~~~~~~~~
41 | d[v] = d[u]+1;
| ~~~~~~~~~~~~~~
42 | dfs(v, u, r);
| ~~~~~~~~~~~~~
43 | }
| ~
44 | }
| ~
45 | });
| ~
test1.cpp:36:31: note: 'main()::<lambda(auto:1, int, int, int&)>::~<lambda>()' is implicitly deleted because the default definition would be ill-formed:
36 | auto dfs = y_combinator([&](auto dfs, int u, int p, int &r) {
| ^
所以我通过捕获 2 个矢量名称 d
和 adj
#include <bits/stdc++.h>
using namespace std;
template<class Fun>
class y_combinator_result {
Fun fun_;
public:
template<class T>
explicit y_combinator_result(T &&fun): fun_(forward<T>(fun)) {}
template<class ...Args>
decltype(auto) operator()(Args &&...args) {
return fun_(ref(*this), forward<Args>(args)...);
}
};
template<class Fun>
decltype(auto) y_combinator(Fun &&fun) {
return y_combinator_result<decay_t<Fun>>(forward<Fun>(fun));
}
int main () {
cin.tie(0)->sync_with_stdio(0);
int N; cin >> N;
vector<int> adj[N+1];
for (int i = 0; i < N-1; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
vector<int> d(N+1);
auto dfs = y_combinator([&d, &adj](auto dfs, int u, int p, int &r) { // I changed this line
if (u == p) d[u] = 0;
if (d[u] > d[r]) r = u;
for (auto &v : adj[u]) {
if (v != p) {
d[v] = d[u]+1;
dfs(v, u, r);
}
}
});
}
并且程序按预期编译...
从我的角度来看,显然有一个非常大的问题:为什么我使用 [&]
捕获 main()
函数内部所有内容的第一段代码失败,但第二段代码有效?有什么办法解决这个问题,因为我不想花时间捕获变量...
P/s : 请原谅我的英语不好。我不是母语人士。
C++ 没有 VLA vector<int> adj[N+1];
。使用此 VLA 会导致编译器错误。参见
使 vector<int> adj[N+1];
-> vector<vector<int>> adj(N+1);
使示例符合要求。