【问题标题】:std thread call template member function of template class: compiler errorstd线程调用模板类的模板成员函数:编译器错误
【发布时间】:2015-04-06 18:28:42
【问题描述】:

这里是代码。它在vs2013中不编译,但在gcc4.8中编译

error C2665: 'std::thread::thread' : 4 个重载都不能转换所有参数类型

由于我使用的是 vs2013,任何人都可以提供解决方法吗?

#include <iostream>
#include <thread>

template<typename T> 
class TestClass
{
public:
    TestClass(){};
    ~TestClass(){};

    T  t;

    template<typename U>
    void fun(U u)
    {
        std::cout << "fun: " << u << '\n';
    }
};

int main()
{
    TestClass<double>  A;

    auto aaa = std::thread(&TestClass<double>::fun<int>, &A, 1);
}

【问题讨论】:

  • 在线程结束前不调用join()detach() 是未定义的行为
  • 你应该打电话给join()
  • @KoushikShetty,实际上,不调用join()detach() 并不是未定义的行为。它导致调用terminate()。 (这比未定义的行为要好,因为你总是会遇到进程崩溃,所以你可以去修复它。)

标签: c++ multithreading c++11


【解决方案1】:

您可以简单地使用 lambda,而不是使用成员函数指针:

auto aaa = thread( [&]{ A.fun(1); } );
aaa.join();

【讨论】:

    【解决方案2】:

    如果您介意的话,还有另一种方法可以解决上述问题! 首先看看线程对象的显式构造函数:

    template< class Function, class... Args > 
    explicit thread( Function&& f, Args&&... args );
    

    f - 函数对象的通用引用。

    args - function(functor) f的可变参数。

    (我不会越来越深入地解释这里使用的可变参数调用)。 所以现在我们知道我们可以处理函子了, 定义一个仿函数(函数对象),如下所示:

    template<typename T>
    class TestClass
    {
    public:
        TestClass(){};
        ~TestClass(){};
    
        T  t;
    
        template<typename U>
        void operator()(U u1,U u2){
            std::cout << "fun: " << u1*u2 << '\n';
        }
    
    };
    int main()
    {
        TestClass<double>  A;
        auto aaa = std::thread(A,1,100);// calling functor A(1,100)
        aaa.join()
        //or if you can move object from main thread to manually created thread aaa ,it's more elegant.
        auto aa = std::thread(std::move(A),1,100);
        aa.join();
        A(1, 99);
        system("Pause");
        return 0;
    }
    

    //请注意这里我没有使用任何储物柜防护系统。 如果您使用 static 函数,则不必每次都绑定相应的实例,这可能会改变您预期的运行时行为,因此您必须进行管理,

     template<typename U>
        static void fun(U u)
        {
            std::cout << "fun: " << u << '\n';
        }
    then invoke the function,
    int main()
    {
        TestClass<double>  A;
        auto aaa = std::thread(&TestClass<double>::fun<int>, 1);
        system("Pause");
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      • 2013-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多