Q: std::packaged_task bug in Visual Studio? I found out that a std::packaged_task couldn't be pushed into a std::vector if the parameter type returns void in Visual Studio (2012, 2013, Nov 2013 CTP). For example,
typedef std::packaged_task<void()> packaged_task;

std::vector<packaged_task> tasks;
packaged_task package;
tasks.push_back(std::move(package));

The error messages are:
error C2182: '_Get_value' : illegal use of type 'void'
error C2182: '_Val' : illegal use of type 'void'
error C2182: '_Val' : illegal use of type 'void'
error C2512: 'std::_Promise<int>' : no appropriate default constructor available
error C2665: 'std::forward' : none of the 2 overloads could convert all the argument types

I think this is bug because this code snippet works if


*

*the return type is not void,

*it is compiled in XCode.


Are there solutions or other options in Visual Studio? I know that boost can be used to replace this.

A: I can reproduce this with a simple auto m = std::move(package);.
int main()
{
    typedef std::packaged_task<void()> packagedtask;
    packagedtask p1;
    packagedtask p2;
    p2 = std::move(p1); // does not cause the error
    auto p3 = std::move(p2); // causes the error
}

Trawling through the code, packaged_task has embedded typedefs as follows;
typedef typename _P_arg_type<_Ret>::type _Ptype;
typedef _Promise<_Ptype> _MyPromiseType;

_P_arg_type offers a non-void type when the return type is void. The packaged_task move constructor contains a reference to the internal _Promise as _Promise<_Ret>;
_MyPromise(_STD forward<_Promise<_Ret> >(_Other._MyPromise))

This then becomes _Promise<void> which in turn generates further invalid code that generates the list of errors seen. It should probably be;
_MyPromise(_STD forward<_MyPromiseType >(_Other._MyPromise))
// possibly even using a move

As the move assignment operator does.
As a workaround, consider adding a "dummy" or "unusable" return type of some sort;
struct unusable {};

Or just simply an int or boost as you have already suggested.
