Recently, I've started using MSVC to compile a code which was always compiled with GCC and Clang. Some piece of this code produces an interesting compilation error (truncated):
C:/data/msvc/14.33.31424-Pre/include\future(311) error C2678: binary '=': no operator found which takes a left-hand operand of type 'const Result' (or there is no acceptable conversion)
<source>(7): note: could be 'Result &Result::operator =(Result &&)'
<source>(7): note: or 'Result &Result::operator =(const Result &)'
Minimal example of this piece of code:
#include <future>
#include <iostream>
struct Result {
int data{0};
};
// getting rid of constness resolves the problem for MSVC
using result_t = const Result;
using promise_result_t = std::promise<result_t>;
auto compute_result(promise_result_t result)
{
Result some_result{10};
result.set_value(std::move(some_result));
}
int main()
{
promise_result_t my_promise;
auto my_future = my_promise.get_future();
std::thread thread(compute_result, std::move(my_promise));
std::cout << "result: " << my_future.get().data;
thread.join();
return 0;
}
- Successful compilation with Clang 11: https://godbolt.org/z/o6Ge85rxG
- Successful compilation with GCC 12: https://godbolt.org/z/x1rhqhfGT
- Error with MSVC 19: https://godbolt.org/z/4jMYhTj3n
It is quite clear that removal of const
for std::promise
storage solves the problem, but I'm curious if anyone has tried to dive deep into the implementations of std::promise
for different compilers.
What might be the difference that allows this code to compile and work using GCC and Clang, yet produce a compilation error when using MSVC? (Operating via pointers on stored data in GCC and Clang?)