多线程模板成员函数错误

Posted

技术标签:

【中文标题】多线程模板成员函数错误【英文标题】:Multithreading template member function error 【发布时间】:2021-09-02 13:53:08 【问题描述】:

我正在测试如何使用此代码创建线程,但遇到此错误。

In file included from rasterization.cpp:1:
rasterization.h: In instantiation of 'void pipeline3D::Rasterizer<Target_t>::render_object(pipeline3D::Object<Triangle, type, Vertex_Shader>) [with type = char; Vertex_Shader = my_shader; Triangle = Triangle; Target_t = char]':
rasterization.cpp:97:40:   required from here
rasterization.h:130:17: error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, pipeline3D::Rasterizer<char>*, Vertex&, Vertex&, Vertex&, my_shader&)'
     std::thread t1(&Rasterizer::render_triangle, this, o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader);

我不明白为什么说函数重载,因为它是文件中唯一具有该名称的函数。我找不到任何与模板有关的类似问题,我尝试了从这里获取的一堆不同的解决方案,但我总是得到同样的错误。

线程的创建是用这段代码。 Thr 是我尝试过的 lambda 版本,但它也不起作用。这是 lambda 版本的错误

rasterization.h: In member function 'void pipeline3D::Rasterizer<Target_t>::render_object(pipeline3D::Object<Triangle, type, Vertex_Shader>)':
rasterization.h:128:27: error: expected primary-expression before '(' token
     auto thr = std::thread( [this, o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader]  render_triangle( o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader);  );
                           ^
rasterization.h:128:37: error: expected ',' before '.' token
     auto thr = std::thread( [this, o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader]  render_triangle( o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader);  );
                                     ^
template<class type, class Vertex_Shader, class Triangle>
        void render_object(Object<Triangle, type, Vertex_Shader> o)
            int size = o.meshsize;
            
            
            for(int i = 0; i<size; i++)
                //auto thr = std::thread( [this, o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader]  render_triangle( o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader);  );
                //thr.join;
                std::thread t1(&Rasterizer::render_triangle, this, o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader);
                t1.join();
                //render_triangle(o.mesh[i].v1,o.mesh[i].v2,o.mesh[i].v3, o.shader);
            
        

函数render_triangle是:


template<class Vertex_Shader, class Vertex>
        void render_triangle(const Vertex &V1, const Vertex& V2, const Vertex &V3, Vertex_Shader shader)
//do work

你能帮帮我吗?

【问题讨论】:

“我不明白为什么它说函数被重载了”——我不明白它确实如此。你能做一个最小的独立示例和/或发布完整的错误吗 【参考方案1】:

您不能获取模板的地址。您只能获取实例化的地址。在您的情况下,您必须提供模板参数:

 std::thread t1(&Rasterizer::render_triangle<decltype(o.mesh[1]), Vertex_Shader>, this, o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader);

也许你有一个更好的 decltype 名称,但你的代码也没有显示 mesh

【讨论】:

我编辑了完整的错误。 Mesh是三角形的向量(模板类型Triangle)【参考方案2】:

我的猜测是,当使用std::thread 的构造函数时,它无法推断出模板参数类型。也许可以尝试这样的事情:

std::thread t1([this, &o]() 
    render_triangle(o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader);
);

或者,如果您不想走 lambda 路线,您可以明确告诉它类型是什么:

std::thread t1(&Rasterizer::render_triangle<Vertex_Shader, /*whatever the Vertex type is*/>, this, o.mesh[i].v1, o.mesh[i].v2, o.mesh[i].v3, o.shader);

【讨论】:

感谢 lambda 版本有效,但在其他解决方案中,顶点是模板类型,我不知道它是什么类型 Vertextype 一样吗?您也许可以使用decltype(o.mesh[i].v1) - 尽管这也可能存在问题?根据错误消息,类型似乎是Vertex

以上是关于多线程模板成员函数错误的主要内容,如果未能解决你的问题,请参考以下文章

成员函数模板错误

std::async 与共享指针模板化成员函数

抛出模板专业化错误的函数指针数组(包括成员函数)

MFC中多线程中静态函数调用成员函数的问题

在VC中,多线程如何调用类得成员函数?

将成员函数传递给模板函数时出现语法错误