问题描述
我有一个类模板 Wrap< T>
使用递归成员函数 test(int)
传递给具有lambda( std :: accumulate
在下面的代码)的STL算法。
I have a class template Wrap<T>
with a recursive member function test(int)
that I want to pass to an STL algorithm with a lambda (std::accumulate
in the code below).
如果我使用默认捕获列表 =
,并使我的递归meber函数 static
,一切都很好,并得到我想要的结果。
If I use a default capture list of =
, and make my recursive meber function static
, all is fine and get the result I want.
但是,如果我使它成为非静态成员函数,Visual C ++和gcc 4.7.2都会抱怨一个单位化的 this
-pointer,除非我将我的递归调用限定为 this-> test()
。
However, if I make it a non-static member function, both Visual C++ and gcc 4.7.2 complain about an unitialized this
-pointer, unless I qualify my recursive call as 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
}
输出:
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-> / *
piece,给出与静态成员函数相同的结果。
Uncommenting the /*this->/*
piece, gives the same result as for the static member function.
为什么需要使用 this->
?
推荐答案
我相信这是GCC 4.7.2的错误。警告说:
I believe this is a bug of GCC 4.7.2. The warning says:
成员'Wrap< T> :: test2(int)缺少初始化器[with T = int] lambda(int,const int&)> :: __ this'
这意味着编译器识别
Which means that the compiler recognizes the this
pointer is to be captured and the generated closure does contain a pointer for it, but that pointer does not get initialized in the closure's constructor.
#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进行编译,确认是否存在错误。
This code compiles fine with Clang 3.2 and VS2012, which seems to confirm the presence of a bug.
这篇关于这个指针捕获在lambda包装器周围的递归函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!