类实例的std :: thread

joh*_*nwi 2 c++ multithreading class c++11

我试图创建该类的两个实例,这些实例最终将使用Win32的mciSendString功能播放音乐文件。但是要进行测试,因为这是我第一次尝试使用std :: thread,所以我编写了一个test(void)方法,该方法输出类ID,我希望可以为我打印一系列的1和2,例如12122111112212121212 ...

我收到以下错误,test(void)方法确实存在吗?

错误1错误C2064:术语未求值为带有0个参数的函数

#include <iostream>
#include <thread>

typedef enum MusicStatus {
    MUSIC_PLAYING = 0, 
    MUSIC_PAUSED, 
    MUSIC_STOPPED, 
    MUSIC_IDLE
} MusicStatus, *pMusicStatus;

class MusicPlayer
{
public:

    MusicPlayer(void) {
        m_bIsPlaying = false;
        m_bIsPaused = false;
    }

    bool isPaused(void) {
        return m_bIsPaused;
    }

    bool isPlaying(void) {
        return m_bIsPlaying;
    }

    MusicStatus getState(void) {
        if ( !m_bIsPlaying && !m_bIsPaused && !m_bIsStopped )
            return MUSIC_IDLE;
        if ( m_bIsPlaying )
            return MUSIC_PLAYING;
        if ( m_bIsPaused ) 
            return MUSIC_PAUSED;
        if ( m_bIsStopped )
            return MUSIC_STOPPED;
        return MUSIC_STOPPED;
    }

    void test(void) {
        for ( int m = 0; m < 100; m++ ) {
            std::cout << this->n;
        }
    }

    int n;

private:

    bool m_bIsPlaying, m_bIsPaused, m_bIsStopped;

};


int main(int argc, char* argv[])
{
    MusicPlayer A;
    MusicPlayer B;
    A.n = 1;
    B.n = 2;

    std::thread t1(A);
    std::thread t2(B);

    t1.join();
    t2.join();

    A.test();
    B.test();

    system("PAUSE");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

更新:我做了一些调整,现在参数列表出现问题,错误:MusicPlayer :: play_sound函数调用缺少参数列表

#include <iostream>

#pragma comment(lib, "Strmiids.lib") 

#include <thread>
#include <dshow.h>
#include "Lib/NSL.h"

typedef enum MusicStatus {
    MUSIC_PLAYING = 0, 
    MUSIC_PAUSED, 
    MUSIC_STOPPED, 
    MUSIC_IDLE
} MusicStatus, *pMusicStatus;

class MusicPlayer
{
public:

    MusicPlayer() {
        m_bIsPlaying = false;
        m_bIsPaused = false;
        m_bIsStopped = false;
    }

    bool isPaused() {
        return m_bIsPaused;
    }

    bool isPlaying() {
        return m_bIsPlaying;
    }

    MusicStatus getState() {
        if ( !m_bIsPlaying && !m_bIsPaused && !m_bIsStopped )
            return MUSIC_IDLE;
        if ( m_bIsPlaying )
            return MUSIC_PLAYING;
        if ( m_bIsPaused ) 
            return MUSIC_PAUSED;
        if ( m_bIsStopped )
            return MUSIC_STOPPED;
        return MUSIC_STOPPED;
    }

    void playAudio(std::string strFilePath) {
        m_strFilePath = strFilePath;
        std::thread audioThread(play_sound);
        audioThread.join();
    }

private:

    bool m_bIsPlaying, m_bIsPaused, m_bIsStopped;
    std::string m_strFilePath;

    void play_sound() {
        IGraphBuilder *pGraph = NULL;
        IMediaControl *pControl = NULL;
        IMediaEvent   *pEvent = NULL;

        // Initialize the COM library.
        HRESULT hr = CoInitialize(NULL);
        if (FAILED(hr))
        {
            printf("ERROR - Could not initialize COM library");
            return;
        }

        // Create the filter graph manager and query for interfaces.
        hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                            IID_IGraphBuilder, (void **)&pGraph);
        if (FAILED(hr))
        {
            printf("ERROR - Could not create the Filter Graph Manager.");
            return;
        }

        hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
        hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

        // Build the graph. IMPORTANT: Change this string to a file on your system.
        hr = pGraph->RenderFile(s2ws(m_strFilePath).c_str(), NULL);
        if (SUCCEEDED(hr))
        {
            // Run the graph.
            hr = pControl->Run();
            if (SUCCEEDED(hr))
            {
                // Wait for completion.
                long evCode;
                pEvent->WaitForCompletion(INFINITE, &evCode);

                // Note: Do not use INFINITE in a real application, because it
                // can block indefinitely.
            }
        }
        pControl->Release();
        pEvent->Release();
        pGraph->Release();
        CoUninitialize();
    }

};

int main(void)
{
    MusicPlayer A;
    A.playAudio("music.mp3");
    system("pause");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Die*_*ühl 5

您不能运行对象!您可以运行的是特定对象上的成员函数:std::thread需要告知线程的入口函数。它使用第一个构造函数参数作为函数对象,并使用所有其他参数作为如何调用函数的参数。由于您的类没有函数调用运算符,因此std::thread不知道要调用哪个函数。

有一种方法可以解决此问题:

  1. 您可以operator()()为您的MusicPlayer类型提供一个函数调用作为线程的入口函数。
  2. 您可以将成员函数用作第一个参数,并将实际对象用作要传递的参数,例如std::thread t1(&MusicPlayer::test, &A)
  3. 您可以使用容易绑定的函数对象作为参数std::thread,例如std::thread t1(std::bind(&MusicPlayer::test, std::ref(A))