Why `std::cout << std::this_thread::get_id()` does not compile?

441 views Asked by At

Why std::cout does not compile in this code snippet,

#include<future>
#include<iostream>
#include<array>
#include<algorithm>

std::array<int, 100> arr;
int sum=0;

struct Wrapper
{   
    void consume()
    {
        std::cout << std::this_thread::get_id() << std::endl;
        std::for_each(arr.begin(), arr.end(), [&sum](int val) {sum+=val; });
        std::cout << sum << std::endl;
    }

    bool produce()
    {
        std::cout << std::this_thread::get_id() << std::endl;

        auto temp = { 1,0,3 };
        return true;
    }
};


int main()
{
    std::fill(arr.begin(), arr.end(), 1);

    std::cout << std::this_thread::get_id() << std::endl;

    Wrapper wrap;
    std::future<bool> fut = std::async(std::launch::async, &Wrapper::produce, &wrap);

    if (fut.get())
        std::async(std::launch::async, &Wrapper::consume, &wrap).get();

}

whereas it compiles in another similar code snippet:


#include <iostream>
#include <thread>

void dosomework()
{
    std::cout << std::this_thread::get_id() << std::endl;
}

int main()
{
    for (int i = 0; i < 10; ++i){
        std::thread connectthread([](){
            dosomework();
        });
        std::cout << "connectthread:" << connectthread.get_id() << std::endl;
        connectthread.join(); 
    }
    return 0;
}

Here is what the compiler comlains for the former code snippet:

<source>: In member function 'void Wrapper::consume()':
<source>:14:53: warning: capture of variable 'sum' with non-automatic storage duration
   14 |             std::for_each(arr.begin(), arr.end(), [&sum](int val) {sum+=val; });
      |                                                     ^~~
<source>:7:9: note: 'int sum' declared here
    7 |     int sum=0;
      |         ^~~
/opt/compiler-explorer/gcc-12.1.0/bin/../lib/gcc/x86_64-linux-gnu/12.1.0/../../../../x86_64-linux-gnu/bin/ld: /tmp/cck5848f.o: in function `main':
<source>:32: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::thread::id)'
/opt/compiler-explorer/gcc-12.1.0/bin/../lib/gcc/x86_64-linux-gnu/12.1.0/../../../../x86_64-linux-gnu/bin/ld: /tmp/cck5848f.o: in function `Wrapper::consume()':
<source>:13: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::thread::id)'
/opt/compiler-explorer/gcc-12.1.0/bin/../lib/gcc/x86_64-linux-gnu/12.1.0/../../../../x86_64-linux-gnu/bin/ld: /tmp/cck5848f.o: in function `Wrapper::produce()':
<source>:20: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::thread::id)'
collect2: error: ld returned 1 exit status

Updated: What a surprise, it compiles on this online compiler.

1

There are 1 answers

7
John On

It needs #include <thread> and it compiles.