【发布时间】:2014-06-04 05:40:16
【问题描述】:
目前 Visual Studio 2013 更新 2 不支持完整的 C++11,其中一项功能是在 lambda 中捕获参数包。有没有一种简单的方法可以解决这个问题,还是我不得不放弃 Visual Studio 并使用兼容的编译器,例如 mingw/g++?
以下代码演示了我所想到的一个简单用例:
template <typename ... Args>
std::thread init_threaded(SomeObject sample, Args && ... args)
{
auto func = [=]()
{
sample->init(args...);
};
return std::thread(func);
}
这在最新的 xcode (5.1.1) 和最新版本的 g++ (使用 4.9.0) 在 linux 下效果很好,但是在 Visual Studio 2013 更新 2 中它给出了错误:
error C2536: 'init_threaded::<lambda_3a984affe0045c597607c0ec0a116b46>::init_threaded::<lambda_3a984affe0045c597607c0ec0a116b46>::<args_0>' : cannot specify explicit initializer for arrays
编辑: 此错误似乎仅在 init 函数中有不同类型时发生。以下示例无法编译。
#include <thread>
struct foo
{
void init(int arg1, std::string arg2) {}
};
template <typename ... Args>
std::thread init_threaded(foo *sample, Args && ... args)
{
auto func = [=]()
{
sample->init(args...);
};
return std::thread(func);
}
int main()
{
foo f;
auto t = init_threaded(&f, 1, "two");
t.join();
}
【问题讨论】:
-
std::thread允许您在构造函数中传递参数。[=](Args... args_){ sample->init(args_...); }然后std::thread(func, std::forward<Args>(args)...)应该可以工作。 -
我已经更新了一个 SSCCE,为了得到上面的例子,我做了很多子系统,结果问题是使用不同类型时,不知道为什么你的 int 和 long 工作但 int 和字符串不起作用。
-
想通了。在上面的示例中,我传递了“两个”,但是如果我传递 std::string("two") 它可以工作。看起来 Visual Studio 没有像所有其他编译器一样将 const char* 转换为 std::string,Visual Studio 在标准上是正确的还是我应该用微软填充一个错误?
-
看起来像一个 MSVC 错误。参数包应该被推断为
(int, char const[4]),但是当你传递给string构造函数时,第二种类型应该衰减为指针(或者甚至当你在lambda中通过值捕获args时,不确定是哪一个)。如果您将 lambda 更改为通过引用捕获,MSVC 会编译代码,但这可能会产生生命周期问题。显式创建string或static_cast<char const *>("two")可能是解决此问题的方法。
标签: c++ c++11 lambda visual-studio-2013