【发布时间】:2012-12-20 22:45:52
【问题描述】:
我有一个调用 lambda 的工作函数模板。
我想将此函数模板概括为采用可变参数并将它们完美地转发到 lambda 中,但我无法编译此代码。
我使用的是 gcc 4.7.2。
更新
根据 R. Martinho Fernandes 的建议,我在 bugzilla -it does look like a bug that's been around for a while 中查找了错误。如果有人知道解决方法(我现在正在寻找一个),请发布答案 - ty。
错误
junk.cpp: In lambda function:
junk.cpp:32:68: error: parameter packs not expanded with ‘...’:
junk.cpp:32:68: note: ‘args’
junk.cpp: In instantiation of ‘std::pair<std::basic_string<char>, typename T::Lambda> MP(const string&, M, Args&& ...) [with T = Integer; M = int (Integer::*)()const; Args = {}; typename T::Lambda = std::function<std::function<int()>(const Integer&)>; std::string = std::basic_string<char>]’:
junk.cpp:47:42: required from here
junk.cpp:34:2: error: using invalid field ‘MP(const string&, M, Args&& ...)::<lambda(const T&)>::__args’
make: *** [junk] Error 1
代码
#include <functional>
#include <iostream>
#include <map>
struct Integer
{
typedef std::function<int()> Function;
typedef std::function<Function( Integer const& inst )> Lambda;
virtual int getInt() const = 0;
};
struct IntImpl : public Integer
{
virtual int getInt() const { return 42; }
};
typedef std::function<int()> IntFunction;
typedef std::function<IntFunction( Integer const& inst )> IntLambda;
#define WONT_COMPILE
template<typename T,typename M,typename... Args>
std::pair<std::string,typename T::Lambda>
MP( std::string const& str, M method, Args&&... args )
{
#ifdef WONT_COMPILE
return std::make_pair( str,
[=]( T const& inst )
{
// COMPILE ERROR (Line 32) on next line
return std::bind( method, std::cref( inst ), std::forward<Args>(args)...);
}
);
#else
return std::make_pair( str,
[method]( T const& inst )
{
return std::bind( method, std::cref( inst ));
}
);
#endif
}
std::map<std::string,IntLambda> const g_intTbl =
{
MP<Integer>( "getInt", &Integer::getInt )
};
int
main( int argv, char* argc[] )
{
IntImpl x;
std::cerr << g_intTbl.find("getInt")->second( x )() << std::endl;
}
【问题讨论】:
-
出现其中一些错误是因为
std::forward<Args>(args...)应该是std::forward<Args>(args)... -
@AndreiTita +1 ty - 这有帮助 - 我仍然遇到错误 - OP 已更新
-
好吧,我不知道您是否可以在 lambda 捕获中扩展可变参数包(稍后会检查),但解决方法是使用像
[=]这样的完整捕获。 -
@AndreiTita @R.MartinhoFernandes 嗯... ...当我用
[=]替换捕获时,它肯定有所改进,但我仍然收到错误(也许是 gcc?) - 我会更新操作 -
似乎是一个 gcc 错误。
标签: c++ binding c++11 lambda variadic-templates