Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Cannot convert lambda to std::packaged_task in std::pair

I did some testing with std::packaged_task and came across this problem.

std::packaged_task<int(void)> task([]() -> int { return 1; });
task();

compiles and calling task() calls the lambda. However, this does not compile:

std::pair<int, std::packaged_task<int(void)>> pair(15, []() -> int { return 15; });
pair.second();

because

error C2664: 'std::pair<int,std::packaged_task<int (void)>>::pair(const std::pair<int,std::packaged_task<int (void)>> &)': cannot convert argument 2 from 'main::<lambda_abbe6cccb9110894d95e872872ec1296>' to 'const std::packaged_task<int (void)> &'

This, however, does compile:

std::vector<std::packaged_task<int()>> v;
v.emplace_back([](){ return 1; })

Why can't I create a pair?

like image 690
Zereges Avatar asked Apr 29 '15 22:04

Zereges


1 Answers

The constructor in question is an explicit constructor. You need to explicitly invoke it for this to compile:

std::pair<int, std::packaged_task<int(void)>> 
    pair(15, std::packaged_task<int(void)>{ []() -> int { return 15; } });

Or, better yet, use std::make_pair:

auto pair = 
    std::make_pair(15, std::packaged_task<int(void)>{ []() -> int { return 15; } });

The case with the vector works, because emplace_back forwards the arguments to the value_type's constructor. If you tried with push_back it wouldn't work.

like image 178
jepio Avatar answered Sep 22 '22 07:09

jepio