在lambda包装器中捕获递归函数的指针
This-pointer capture in lambda wrapper around recursive function
我有一个类模板Wrap<T>
与递归成员函数test(int)
,我想传递给STL算法与lambda (std::accumulate
在下面的代码)。
如果我使用=
的默认捕获列表,并使我的递归成员函数static
,一切都很好,并得到我想要的结果。
然而,如果我使它成为一个非静态成员函数,visualc++和gcc 4.7.2都会抱怨一个初始化的this
指针,除非我将递归调用限定为this->test()
。
#include <algorithm>
#include <iostream>
#include <vector>
template<typename T>
struct Wrap
{
static int test1(int depth)
{
std::vector<int> v = { 0, 1, 2, 3 };
return depth == 0? 1 : std::accumulate(v.begin(), v.end(), int(0), [=](int sub, int const&) {
return sub + test1(depth - 1);
});
}
int test2(int depth)
{
std::vector<int> v = { 0, 1, 2, 3 };
return depth == 0? 1 : std::accumulate(v.begin(), v.end(), int(0), [=](int sub, int const&) {
return sub + /*this->*/test2(depth - 1);
});
}
};
int main()
{
std::cout << Wrap<int>::test1(0) << "n"; // 1
std::cout << Wrap<int>::test1(1) << "n"; // 4
std::cout << Wrap<int>::test1(2) << "n"; // 16
Wrap<int> w;
std::cout << w.test2(0) << "n"; // 1
std::cout << w.test2(1) << "n"; // 4
std::cout << w.test2(2) << "n"; // 16
}
LiveWorkSpace的输出:
source.cpp: In instantiation of 'int Wrap<T>::test2(int) [with T = int]':
source.cpp:32:26: required from here
source.cpp:19:74: error: missing initializer for member 'Wrap<T>::test2(int) [with T = int]::<lambda(int, const int&)>::__this' [-Werror=missing-field-initializers]
取消注释/*this->/*
片段,得到与静态成员函数相同的结果。
为什么我需要用this->
限定我的递归调用?
我相信这是GCC 4.7.2的一个bug。警告显示:
missing initializer for member 'Wrap<T>::test2(int) [with T = int]::<lambda(int, const int&)>::__this'
这意味着编译器识别出this
指针将被捕获,并且生成的闭包确实包含它的指针,但该指针没有在闭包的构造函数中初始化。
尝试访问/更改成员变量(在示例中不存在,但可以很容易地添加)会导致运行时错误,这一事实证实了这一点。例如,这显示liveworkspace.org
没有输出#include <algorithm>
#include <iostream>
#include <vector>
template<typename T>
struct Wrap
{
int test2(int depth)
{
m_test++;
std::vector<int> v = { 0, 1, 2, 3 };
return depth == 0? 1 : std::accumulate(
v.begin(), v.end(), int(0), [=](int sub, int const&) {
return sub + /*this->*/test2(depth - 1);
});
}
int m_test = 0;
};
int main()
{
Wrap<int> w;
std::cout << w.test2(2) << "n"; // 1
}
这段代码在Clang 3.2和VS2012下可以正常编译,这似乎证实了一个bug的存在。
相关文章:
- 递归函数计算序列中的平方和(并输出过程)
- 如何在Elixir中调用递归函数并行
- 递归函数有效,但无法记忆
- 为什么我的递归函数按降序打印,然后按升序打印?
- 为什么递归函数的最终输出是 5?
- 有没有办法使用递归函数找到数组中最小值的 INDEX?C++
- 如何将记忆应用于此递归函数?
- 如何从递归函数中完全返回,该函数给出了每个函数结果的累积相加?
- 无穷大而循环时具有递归函数
- 即使没有调用这个递归函数,它是如何工作的?
- 如何使此递归函数从给定的起始位置返回最小的整数?
- 此递归函数的每次迭代的值存储在哪里?
- 可以清除递归函数中的变量吗?
- 尝试使用递归和指针到指针反转链表,但反转函数没有给出预期的正确输出
- 在递归函数中创建 std::list of value 而不是 std::list of 指针
- munmap_chunk():递归函数中的无效指针:0x00007fffbef49d90
- 了解递归函数中的数组和指针
- 如何从递归函数返回指针,该函数将抛光表示法转换为反向抛光表示法
- 为什么在NULL检查之后要在指针上调用递归函数?
- 在lambda包装器中捕获递归函数的指针