Unverständliche Fehlermeldung bei der Verwendung von std::mutex und lock_guard



  • Ich habe mir gerade selbst ein minimales Beispiel mit std::threads geschrieben, als Versuchsanordnung und bin dabei auf folgendes Problem gestoßen:

    #include <iostream>
    #include <mutex>
    #include <thread>
    #include <algorithm>
    #include <string>
    
    class Job
    {
        std::mutex m_mutex;
    public:
        Job()
        {}
    
        ~Job()
        {}
    
        void operator()()
        {
            std::lock_guard<std::mutex> lock(m_mutex);
            std::cout << "Thread here" << std::endl;
        }
    };
    
    int main()
    {
        Job j;
        std::thread t(j);
        std::thread t2(j);
        std::thread t3(j);
        t.join();
        t2.join();
        t3.join();
    }
    

    E:\Programming\experiments>cl /EHsc threads.cpp
    Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25019 for x64
    Copyright (C) Microsoft Corporation. All rights reserved.

    threads.cpp
    D:\Microsoft Visual Studio 2017\VC\Tools\MSVC\14.10.25017\include\memory(2054): error C2665: 'std::tuple<Job>::tuple': none of the 2 overloads could convert all the argument types
    D:\Microsoft Visual Studio 2017\VC\Tools\MSVC\14.10.25017\include\tuple(552): note: could be 'std::tuple<Job>::tuple(std::tuple<Job> &&)'
    D:\Microsoft Visual Studio 2017\VC\Tools\MSVC\14.10.25017\include\tuple(551): note: or 'std::tuple<Job>::tuple(const std::tuple<Job> &)'
    D:\Microsoft Visual Studio 2017\VC\Tools\MSVC\14.10.25017\include\memory(2054): note: while trying to match the argument list '(Job)'
    D:\Microsoft Visual Studio 2017\VC\Tools\MSVC\14.10.25017\include\thread(49): note: see reference to function template instantiation 'std::unique_ptr<std::tuple<Job>,std::default_delete<_Ty>> std::make_unique<std::tuple<Job>,Job&>(Job &)' being compiled
    with
    [
    _Ty=std::tuple<Job>
    ]
    threads.cpp(29): note: see reference to function template instantiation 'std::thread::thread<Job&,,void>(_Fn)' being compiled
    with
    [
    _Fn=Job &
    ]

    Das ganze verschwindet, sobald ich den std::mutex aus der Memberlist der Klasse Job entferne.
    Ich verstehe nicht ganz, wieso diese Fehlermeldung hier auftaucht und was sie mit tuple zu tun hat.
    Kann hier jemand Licht ins Dunkel bringen bitte?



  • Hi,

    der Konstruktor von std::thread versucht den Funktor zu kopieren und scheitert, da std::mutex nicht kopierbar ist. Um das Problem zu lösen nutzt du std::ref; damit sieht das dann so aus:

    std::thread t{ std::ref( j ) };
        std::thread t2{ std::ref( j ) };
        std::thread t3{ std::ref( j ) };
    

    LG


Log in to reply