gpt4 book ai didi

c++ - 将模板参数传递给线程中的模板函数

转载 作者:行者123 更新时间:2023-11-30 02:45:57 24 4
gpt4 key购买 nike

我是模板的新手,所以我决定为我正在编写的一些并发代码编写单元测试,但我似乎无法让它们编译。具体报错是:

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 dumpster\utility_unittests\utspinlock.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 2013

using 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 实现中的一个错误。当 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); });

关于c++ - 将模板参数传递给线程中的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24051019/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com