初始化存储 lambda 函数的 C++ 静态成员
Initializing a C++ static member that stores a lambda function
我定义了一个结构 A,其成员 f 包含一个 lambda
功能。类型作为模板参数给出,f 是
使用参数在构造函数中初始化
构造函数。以下代码运行良好。
template <typename f_t>
struct A {
f_t f; // (1)
int k;
A(f_t arg_f, int arg_k) : f(arg_f), k(arg_k) {} // (2)
int g(int x) { return f(f(x)) + k; }
};
现在我想要一个具有相同 lambda 函数的结构 A 向量。
int main() {
int p, q; std::cin >> p >> q;
auto f1 = [&](int x) -> int { return p * x + q; };
auto f2 = [&](int x) -> int { return p * x - q; };
std::vector<A<decltype(f1)>> vec_a1; // (3)
std::vector<A<decltype(f2)>> vec_a2;
for (int i = 0; i < 10000; i++) {
int k; std::cin >> k;
vec_a1.emplace_back(f1, k);
vec_a2.emplace_back(f2, k);
}
// ....
return 0;
}
对于这段代码,我认为结构 A 的成员 f 应该是
静态保存 space。但是,如果我将第 (1) 行更改为:
static f_t f;
那么,自然是不能在构造函数中初始化了。
第 (2) 行产生以下错误:
error: ‘f_t A<f_t>::f’ is a static data member; it can only be initialized at its definition
作业也不允许,因为已删除作业
操作员。如果我在第 (3) 行之后添加以下内容:
A<decltype(f1)>::f = f1
报如下错误:
error: use of deleted function 'main(int, char**)::<lambda(int)>& main(int, char**)::<lambda(int)>::operator=(const main(int, char**)::<lambda(int)>&)'
(貌似会导致linker error 但是对于这个错误。)
如何初始化成员f?
为了节省空间,您可以重新设计为:
template <typename F>
struct A {
F f;
std::vector<int>* v;
A(F f, std::vector<int>* v) : f(f), v(v) {}
int g(int i, int x) { return f(f(x)) + v[i]; }
};
nt main() {
int p, q; std::cin >> p >> q;
auto f1 = [&](int x) -> int { return p * x + q; };
auto f2 = [&](int x) -> int { return p * x - q; };
std::vector<int> v;
for (int i = 0; i < 10'000; i++) {
int k; std::cin >> k;
v.emplace_back(k);
}
A<decltype(f1)> a1(f1, &v);
A<decltype(f2)> a2(f2, &v);
// ...
}
因此您只存储每个值 f1
、f2
和 k
一次。
而您存储 10.000
时间 f1
、f2
和每个 k
两次。
使用起来可能不太方便。通常在不同类型的优化 (memory/speed) 本身、安全性和 readability/simplicity.
之间进行权衡
我定义了一个结构 A,其成员 f 包含一个 lambda 功能。类型作为模板参数给出,f 是 使用参数在构造函数中初始化 构造函数。以下代码运行良好。
template <typename f_t>
struct A {
f_t f; // (1)
int k;
A(f_t arg_f, int arg_k) : f(arg_f), k(arg_k) {} // (2)
int g(int x) { return f(f(x)) + k; }
};
现在我想要一个具有相同 lambda 函数的结构 A 向量。
int main() {
int p, q; std::cin >> p >> q;
auto f1 = [&](int x) -> int { return p * x + q; };
auto f2 = [&](int x) -> int { return p * x - q; };
std::vector<A<decltype(f1)>> vec_a1; // (3)
std::vector<A<decltype(f2)>> vec_a2;
for (int i = 0; i < 10000; i++) {
int k; std::cin >> k;
vec_a1.emplace_back(f1, k);
vec_a2.emplace_back(f2, k);
}
// ....
return 0;
}
对于这段代码,我认为结构 A 的成员 f 应该是 静态保存 space。但是,如果我将第 (1) 行更改为:
static f_t f;
那么,自然是不能在构造函数中初始化了。 第 (2) 行产生以下错误:
error: ‘f_t A<f_t>::f’ is a static data member; it can only be initialized at its definition
作业也不允许,因为已删除作业 操作员。如果我在第 (3) 行之后添加以下内容:
A<decltype(f1)>::f = f1
报如下错误:
error: use of deleted function 'main(int, char**)::<lambda(int)>& main(int, char**)::<lambda(int)>::operator=(const main(int, char**)::<lambda(int)>&)'
(貌似会导致linker error 但是对于这个错误。)
如何初始化成员f?
为了节省空间,您可以重新设计为:
template <typename F>
struct A {
F f;
std::vector<int>* v;
A(F f, std::vector<int>* v) : f(f), v(v) {}
int g(int i, int x) { return f(f(x)) + v[i]; }
};
nt main() {
int p, q; std::cin >> p >> q;
auto f1 = [&](int x) -> int { return p * x + q; };
auto f2 = [&](int x) -> int { return p * x - q; };
std::vector<int> v;
for (int i = 0; i < 10'000; i++) {
int k; std::cin >> k;
v.emplace_back(k);
}
A<decltype(f1)> a1(f1, &v);
A<decltype(f2)> a2(f2, &v);
// ...
}
因此您只存储每个值 f1
、f2
和 k
一次。
而您存储 10.000
时间 f1
、f2
和每个 k
两次。
使用起来可能不太方便。通常在不同类型的优化 (memory/speed) 本身、安全性和 readability/simplicity.
之间进行权衡