The following piece of code (which is supposed to crash) is compilable using MSVC but not in g++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
#include <iostream>
#include <unordered_map>
#include <thread>
using namespace std;
void thread_add(unordered_map<int, int>& ht, int from, int to)
{
for(int i = from; i <= to; ++i)
ht.insert(unordered_map<int, int>::value_type(i, 0));
}
void main()
{
unordered_map<int, int> ht;
thread t[2];
t[0] = thread(thread_add, ht, 0, 9);
t[1] = thread(thread_add, ht, 10, 19);
t[0].join();
t[1].join();
std::cout << "size: " << ht.size() << std::endl;
}
|
g++ gives the following error:
error: no type named ‘type’ in ‘class std::result_of ...
g++ require explicit reference cast to compile:
t[0] = thread(thread_add, ref(ht), 0, 9);
Although MSVC compiles successfully but it does not run correctly, because it passes in a temporarily created object instead of the reference to the original object, which is even worse.
The g++ compilation error is saying that the compiler cannot decide whether to pass in the reference of the original object or a newly created temporary object. However, this is unnecessary because it can be easily deduced from the definition of the thread_add function whether to pass in the reference of the original object or the temporarily created object, e.g.,
void thread_add(unordered_map<int, int>& ht, int from, int to);
void thread_add(unordered_map<int, int> ht, int from, int to);
I hope the compiler can be improved to resolve all these deducible parameter types so that programmers do not need to explicitly write the reference cast std::ref() every time, like what has been done in MSVC.