我有一个回调实现,它使用右值引用来存储与 gcc 一起工作的参数,但在某些代码上无法在 VS 2010 中编译。一个简短的版本:
#include <iostream>
#include <string>
class B {
public:
virtual void execute() = 0;
};
template<typename FuncType, typename ArgType>
class F : public B {
public:
F(FuncType func, ArgType && arg) : f(func), arg(arg) {}
void execute() { f(arg); }
private:
FuncType f;
ArgType && arg;
};
template<typename FuncType, typename ArgType>
B * registerFunc(FuncType func, ArgType && arg)
{
return new F<FuncType, ArgType>(func, arg);
}
void myFunction(std::string text)
{
std::cout << "Function " << text << " here" << std::endl;
}
int main()
{
const char text1[] = "sample1";
std::string text2("sample2");
B * b = registerFunc(myFunction, text1);
b->execute();
delete b;
b = registerFunc(myFunction, text2);
b->execute();
delete b;
// VS 2010 fails because of this call
b = registerFunc(myFunction, text2.c_str());
b->execute();
delete b;
return 0;
}
使用 gcc 4.4 这会产生:
$ g++ clbck.cpp -std=c++0x -o clbck && ./clbck
函数 sample1 这里
函数 sample2 这里
函数 sample2 这里
但是,由于标记的行,当尝试实例化 registerFunc 时,它无法在 VS 2010 中编译:
错误 C2664: 'F::F(FuncType,ArgType &&)' : 无法
使用
[
FuncType=void (__cdecl *)(std::string),
ArgType将参数 2 从 'const char *' 转换为 'const char *&&' =const char *
]
你不能将左值绑定到右值引用
谷歌搜索在 VS2010 上发现了与 Boost 1.44 类似的错误,但推荐的解决方案是根本不使用右值引用。真的没有别的办法了吗?
当您这样做时,我处理这些回调的方式有问题吗?它适用于函数指针和仿函数(我还没有测试过 lambdas),我发现的唯一缺点是上面描述的那个。(请记住,这里显示的代码只是一个小演示,在实际代码中我没有给用户任何指针;我实际上是在使用它在 Qt 应用程序的不同线程中执行函数)。