【问题标题】:Thread calling function with non-static members failing非静态成员的线程调用函数失败
【发布时间】:2020-10-04 07:43:30
【问题描述】:

我创建了一个函数void top(),通过为每个像素发送一条射线来渲染图像。我想把它放在一个线程上。我使用了#include <thread> 库,但是当我在main() 方法中声明线程时,它给了我两个错误: Error C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&.. .) noexcept()错误 C2672 'std::invoke': 没有匹配的重载函数。我认为这可能是因为void top() 调用了非静态和静态方法。刚刚学习线程,所以对出了什么问题有点困惑。以下所有函数都在主 cpp 文件中。

void top(int& samples_per_pixel, camera& cam, const color& background, hittable& world, const int& max_depth) {
    for (float j = image_height - 1; j >= image_height/2; --j) {
        for (int i = 0; i < image_width; ++i) {
            color pixel_color(0, 0, 0);
            for (int s = 0; s < samples_per_pixel; ++s) {
                auto u = (i + random_double()) / (image_width - 1); //Random double is static. From other header file
                auto v = (j + random_double()) / (image_height - 1);
                ray r = cam.get_ray(u, v); //get_ray() is non-static and in camera class
                pixel_color += ray_color(r, background, world, max_depth); //Ray_color defined above top() method in same main cpp file
                pixel_color += color(0, 0, 0);
            }

            auto r = pixel_color.x();
            auto g = pixel_color.y();
            auto b = pixel_color.z();

            auto scale = 1.0 / samples_per_pixel;
            r = sqrt(scale * r);
            g = sqrt(scale * g);
            b = sqrt(scale * b);

            int ir = static_cast<int>(256 * clamp(r, 0.0, 0.999));
            int ig = static_cast<int>(256 * clamp(g, 0.0, 0.999));
            int ib = static_cast<int>(256 * clamp(b, 0.0, 0.999));

            pixels[index++] = ir; //pixels defined above top() class
            pixels[index++] = ig;
            pixels[index++] = ib;

        }

    }
}

...

int main(){
...

std::thread first(top,samples_per_pixel, cam, background, world, max_depth); //Two errors being called here
first.detach();

}

【问题讨论】:

  • 我认为你需要在std::ref 的main 中包装你的引用调用参数。此外,通过引用传递 int 之类的原始类型也没有任何意义。它没有增加任何东西,而且效率较低。
  • @TedLyngmo 对不起,我是这个网站的新手,不知道那是一回事;现在才做

标签: c++ multithreading methods static-methods


【解决方案1】:

来自`std::thread::thread

线程函数的参数按值移动或复制。如果需要将引用参数传递给线程函数,则必须对其进行包装(例如,使用 std::refstd::cref)。

因此,只需将您通过引用获取的每个变量包装在其中一个包装器中。 如果您不更改线程内的值并相应地调整函数的签名,则首选std::cref

不要传递const int&amp;,而是传递int

例子:

// new signature:
void top(int samples_per_pixel, camera& cam, const color& background,
         hittable& world, int max_depth);

// new starting call:
std::thread first(top, samples_per_pixel, std::ref(cam), std::cref(background),
                  std::ref(world), max_depth);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多