将模板参数传递给线程中的模板函数
Passing template argument to template function in a thread
我是模板的新手,所以我决定为我正在编写的一些并发代码编写单元测试,但我似乎无法让它们编译。具体错误为:
error C2664: 'std::thread::thread(const std::thread &)' : cannot convert argument 1 from 'void (__cdecl *)(lock &)' to 'void (__cdecl &)(Utility_UnitTests::emptyLock &)'
1> None of the functions with this name in scope match the target type
1> w:code dumpsterutility_unittestsutspinlock.cpp(88) : see reference to function template instantiation 'void Utility_UnitTests::UTSpinLock::lockContension<Utility_UnitTests::emptyLock>(lock &)' being compiled
1> with
1> [
1> lock=Utility_UnitTests::emptyLock
1> ]
这个问题从编译器很清楚,我没有传递正确的类型,但我不知道如何修复它!提前感谢!
编辑:我忘了说,我用的是Visual Studio 2013using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace Utility_UnitTests
{
typedef utils::threading::SpinLock<utils::threading::backoff::empty> emptyLock;
typedef utils::threading::SpinLock<utils::threading::backoff::yield> yieldingLock;
typedef utils::threading::SpinLock<utils::threading::backoff::pause> pausingLock;
TEST_CLASS(UTSpinLock)
{
public:
template<typename lock>
void lockAndSleepT(lock &l)
{
l.lock();
std::this_thread::sleep_for(std::chrono::nanoseconds(10));
l.unlock();
}
template<typename lock>
void lockContension(lock &l)
{
std::thread t1(&UTSpinLock::lockAndSleepT<lock>, this, std::ref(l));
Assert::AreEqual(true, l.isLocked());
t1.join();
Assert::AreEqual(false, l.isLocked());
}
TEST_METHOD(testLockContension)
{
UTSpinLock::lockContension(m_emptySpin);
UTSpinLock::lockContension(m_yieldingSpin);
UTSpinLock::lockContension(m_pausingSpin);
}
private:
emptyLock m_emptySpin;
yieldingLock m_yieldingSpin;
pausingLock m_pausingSpin;
};
}
首先,这肯定是MSVC实现中的一个bug。当std::thread
的第一个参数是指向成员函数模板的指针时,它似乎遇到了麻烦。在我的机器上,64位编译器产生相同的错误消息,而32位编译器崩溃。值得庆幸的是,您可以通过多种方式解决这个问题,所有这些方法都不涉及直接将指向成员函数模板的指针传递给thread
。
选项1 -正如您所发现的,创建bind
表达式并将其传递给thread
工作。
选项2 -重写类,使其成为模板,而成员函数不是。
template<typename lock>
struct UTSpinLock
{
public:
void lockAndSleepT(lock &l)
{}
void lockContension(lock &l)
{
std::thread t1(&UTSpinLock::lockAndSleepT, this, std::ref(l));
t1.join();
}
};
选项3 -保持类定义不变,并将指向成员函数模板的指针包装在std::mem_fn
std::thread t1(std::mem_fn(&UTSpinLock::lockAndSleepT<lock>), this, std::ref(l));
选项4—不再更改类定义,这次将lambda表达式传递给thread
std::thread t1([&, this](){ lockAndSleepT(l); });
特别感谢WhozCraig!我会接受他的回答,但是,出于某种原因,我不能。对于那些感兴趣的人,我更改了:
template<typename lock>
void lockContension(lock &l)
{
std::thread t1(&UTSpinLock::lockAndSleepT<lock>, this, std::ref(l));
Assert::AreEqual(true, l.isLocked());
t1.join();
Assert::AreEqual(false, l.isLocked());
}
:
template<typename lock>
void lockContension(lock &l)
{
auto bounded = std::bind(&UTSpinLock::lockAndSleepT<lock>, this, std::placeholders::_1);
std::thread t1(bounded, std::ref(l));
Assert::AreEqual(true, l.isLocked());
t1.join();
Assert::AreEqual(false, l.isLocked());
}
相关文章:
- 如何在C++中将迭代器作为函数参数传递
- 为什么我不能将引用作为 std::async 的函数参数传递
- 节点插件 API 将数组作为函数参数传递
- 将字符串数组作为函数参数传递
- 如何通过 C++ 中的函数参数传递初始值设定项列表的固定大小的初始值设定项列表?
- 我可以动态创建新地图并作为函数参数传递吗?
- 将任意模板向量作为函数参数C++传递
- 将函数指针作为函数参数传递的目的
- C++:通过函数参数传递的值给出不同的结果
- 当数组大小在C++中未知时,如何在运行时将对字符串数组的引用作为函数参数传递?
- 通过宏将函数参数传递给函数
- C++:访问作为函数参数传递的双指针数组所指向的变量的值
- 如何将 std::string 作为构造函数参数传递,并将其保存的 C 字符串存储在 void 指针中?
- 将派生类构造函数参数传递给受保护的成员
- 将指向数组的指针作为函数参数传递,这本身就是另一个函数的返回值?
- 如何将二维数组类型字符(字符串)作为函数参数传递?
- 有什么理由C++ 11+ std::mutex 应该声明为全局变量,而不是作为函数参数传递到 std::thread 中
- 如何将派生类作为函数参数传递:如果派生类成员不在父类中怎么办
- 如何将变量作为构造函数参数或函数参数传递
- 当数组对象以函数参数传递时,为什么复制构造函数会自称