C++ std::invoke 找不到匹配的重载函数在 VS 2015 中给出的错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40353512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:22:21  来源:igfitidea点击:

std::invoke no matching overloaded function found error given in VS 2015

c++c++11

提问by cp18

I'm very new to C++ and SDL and I am trying to create a thread that constantly updates the screen but the I keep getting the following errors:

我对 C++ 和 SDL 非常陌生,我正在尝试创建一个不断更新屏幕的线程,但我不断收到以下错误:

'std::invoke no matching overloaded function found'

'std::invoke 没有找到匹配的重载函数'

and

'Failed to specialize function template 'unknown-type std::invoke(Callable &&,_Types&&...)''

'未能专门化函数模板'未知类型的 std::invoke(Callable &&,_Types&&...)''

main.cpp

主程序

  int main(int argc, char **argv) {
    using namespace std::placeholders;
    bool gameover = false;
    int test;
    std::string filepath = getResourcePath("Lesson1");

    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {               // Intializes SDL functionality
        std::cout << "Could not start SDL" << std::endl;
        std::cin >> test;
        return 1;
    }
    else {
        std::cout << "SDL started successfully!" << std::endl;
    }

    viewWindow window;                                  // Class representing the window in which the program is run.


    SDL_Renderer *render = window.render();         // Pointer to the renderer used to draw images to the window.
    if (render == nullptr) {
        std::cout << "There was an error creating the renderer" << std::endl << SDL_GetError() << std::endl;
        std::cin >> test;
        return 1;
    }

    SDL_Surface *emptySurface = window.blankSurface();   // Temp surface to draw background to
    if (emptySurface == nullptr) {
        std::cout << "Unable to create a blank surface " << std::endl << SDL_GetError() << std::endl;;
        std::cin >> test;
        return 1;
    }

    surfaces background;

    background.filename = "grass.bmp";

    SDL_Surface *backgroundSurface = background.loadSurface(filepath); 
    if (backgroundSurface == nullptr) {
        std::cout << "Unable to create background surface" << std::endl << SDL_GetError() << std::endl;
        std::cin >> test;
        return 1;
    }

    SDL_Rect backgroundRect;

        SDL_Texture *backTexture = background.blitBack(render, backgroundRect, backgroundSurface, emptySurface);



        player player;

        SDL_Rect playerRect;
        playerRect.x = 320;
        playerRect.y = 240;
        playerRect.h = 16;
        playerRect.w = 16;


        SDL_Texture *playerTexture = player.createPlayerTexture(render, filepath);
        if (playerTexture == nullptr) {
            std::cout << "Could not load player texture" << std::endl << SDL_GetError() << std::endl;
            std::cin >> test;
            return 1;
        }

        while (!gameover) {
            std::thread t((&viewWindow::refreshWindow, render, playerRect, backTexture, playerTexture));
            playerRect.x = player.moveX(playerRect);
            playerRect.y = player.moveY(playerRect);
            t.join();
        }


    return 0;
   }

viewWindow.h

视窗.h

   #pragma once
#ifndef VIEWINDOW_H
#define VIEWWINDOW_H
#include "SDL.h"



class viewWindow                // Class representing the window.
{
private:
    char winName[45] = "Game Test";
    int winWidth = 640;
    int winHeight = 480;
    int xPos = 960;
    int yPos = 540;


public:


     SDL_Window *view();    // Intializing funtions for creating the window and renderer.

     SDL_Renderer *render();

     SDL_Surface *blankSurface();

    void refreshWindow(SDL_Renderer *renderer, SDL_Rect &playerRect, SDL_Texture *backtex, SDL_Texture *playertex);

};


#endif

viewWindow.cpp

视图窗口.cpp

   #include "viewWindow.h"
#include <string>
#include "SDL.h"


SDL_Window *viewWindow::view()      
{
    SDL_Window *createdwindow = SDL_CreateWindow(winName, xPos, yPos, winWidth, winHeight, SDL_WINDOW_SHOWN);
    return createdwindow;

}

SDL_Renderer *viewWindow::render() {

    SDL_Renderer *render = SDL_CreateRenderer(view(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    return render;
}

SDL_Surface *viewWindow::blankSurface() {
    SDL_Surface *blacksurface = SDL_CreateRGBSurface(0, winWidth, winHeight, 32, 0, 0, 0, 0);
    return blacksurface;
}

void  viewWindow::refreshWindow(SDL_Renderer *renderer, SDL_Rect &playerRect, SDL_Texture *backtex, SDL_Texture *playertex) {
    while (true) {
        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, backtex, NULL, NULL);
        SDL_RenderCopy(renderer, playertex, NULL, &playerRect);
        SDL_RenderPresent(renderer);
    }

}

回答by Nikita

Method refreshWindowis not static. std::invokerequires the object instance of viewWindowclass to call this method. You should pass it as a second parameter into the threadconstructor:

方法refreshWindow不是staticstd::invoke需要viewWindow类的对象实例来调用这个方法。您应该将它作为第二个参数传递给thread构造函数:

std::thread t(&viewWindow::refreshWindow, window, render, std::ref(playerRect), backTexture, playerTexture);   

Instead of function pointer you could use lambda function:

您可以使用lambda 函数代替函数指针:

std::thread t([&](viewWindow* view){ view->refreshWindow(render, playerRect, backTexture, playerTexture); }, &window);