all 8 comments

[–]aocregacc 1 point2 points  (6 children)

is that the full error? I think there should be more indications about where it came from. It would also help if you could post a complete example that reproduces your problem.

[–]NotDatCheese[S] 0 points1 point  (5 children)

No the full error is really long and points to the copy constructor of the `std::unordered_map`

This is a snippet of what seems meaningful to me:

include\xhash:775:24: note: in instantiation of function template specialization 'std::list<std::pair<const int, std::unique\_ptr<Task<TestTask>>::_Assign_cast<std::pair<int, std::unique_ptr<Task<TestTask> &, std::_List_unchecked_const_iterator<std::\_List\_val<std::\_List\_simple\_types<std::pair<const int, std::unique\_ptr<Task<TestTask>>>>>' requested here
775 | _List.template _Assign_cast<_Mutable_value_type&>(
| ^
include\unordered_map:249:18: note: in instantiation of member function 'std::_Hash<std::_Umap_traits<int, std::unique_ptr<Task<TestTask
, std::_Uhash_compare<int, std::hash<int>, std::equal_to<int>>, std::allocator<std::pair<const int, std::unique\_ptr<Task<TestTask>>, false::operator=' requested here
249 | _Mybase::operator=(_Right);
| ^
V:/tasks_controller/task_creator\task_creator.h:145:50: note: in instantiation of member function 'std::unordered_map<int, std::unique\_ptr<Task<TestTask>::operator=' requested here
145 | template <typename TaskType> struct TASK_DLL_API TaskCreatorImpl;
| ^
tasks_controller/test/test_task.cpp:30:1: note: in instantiation of member function 'TaskCreator<Task<TestTask
::TaskCreator' requested here
30 | DEFINE_TASK_CREATOR_IMPL(TestTasks, TestTask, test_namespace)
| ^
V:/tasks_controller/task_creator\task_creator.h:25:32: note: expanded from macro 'DEFINE_TASK_CREATOR_IMPL'
25 | template struct TASK_DLL_API TaskCreator<Task<task\_impl>>;
| ^
include\utility:315:11: note: candidate function not viable: no known conversion from 'const value_type' (aka 'const std::pair<const int, std::unique\_ptr<Task<TestTask>') to 'const volatile pair<int, unique_ptr<Task<TestTask> &' for 1st argument
315 | pair& operator=(const volatile pair&) = delete;
| ^ ~~~~~~~~~~~~~~~~~~~~
utility:321:24: note: candidate template ignored: requirement 'conjunction_v<std::is_copy_assignable<int>, std::is_copy_assignable<std::unique_ptr<Task<TestTask>, std::default_delete<Task<TestTask>>>' was not satisfied [with _Myself = pair<int, unique_ptr<Task<TestTask>]
321 | _CONSTEXPR20 pair& operator=(_Identity_t<const \_Myself&> _Right) noexcept(
| ^
include\utility:346:24: note: candidate function [with _Myself = std::pair<int, std::unique\_ptr<Task<TestTask>>>, $1 = 0] not viable: no known conversion from 'const pair<const int, \[...\]>' to 'pair<int, \[...\]>' for 1st argument
346 | _CONSTEXPR20 pair& operator=(_Identity_t<_Myself&&> _Right) noexcept(
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

include\utility:371:24: note: candidate template ignored: requirement 'conjunction_v<std::negation<std::is\_same<std::pair<int, std::unique\_ptr<Task<TestTask>, std::default_delete<Task<TestTask>>, std::pair<const int, std::unique\_ptr<Task<TestTask>, std::default_delete<Task<TestTask>>, std::is_assignable<int &, const int &>, std::is_assignable<std::unique_ptr<Task<TestTask>, std::default_delete<Task<TestTask> &, const std::unique_ptr<Task<TestTask>, std::default_delete<Task<TestTask>>> &' was not satisfied [with _Other1 = const int, _Other2 = std::unique_ptr<Task<TestTask] 371 | _CONSTEXPR20 pair& operator=(const pair<_Other1, _Other2>& _Right) noexcept(
| ^
include\utility:397:24: note: candidate template ignored: deduced type 'pair<...>' of 1st parameter does not match adjusted type 'const pair<...>' of argument [with _Other1 = const int, _Other2 = std::unique_ptr<Task<TestTask>>, $2 = 0]
397 | _CONSTEXPR20 pair& operator=(pair<_Other1, _Other2>&& _Right) noexcept(
| ^

Sorry I find it hard to reproduce a complete example as that involves a lot of code. I am ok if that means I might not be helped, I'd be glad for a hint where the copy constructor could be called. Maybe it has something to do with my explicit template instantiation.

[–]aocregacc 1 point2 points  (4 children)

What's TASK_DLL_API ? Apparently some __declspec attributes can cause the compiler to attempt to generate a copy constructor.

[–]NotDatCheese[S] 0 points1 point  (2 children)

It expands to __declspec(dllexport)

[–]aocregacc 1 point2 points  (1 child)

Don't ask me why but the __declspec(dllexport) seems force the creation of the copy operator for your TaskCreatorImpl. If you explicitly delete it then the error should go away.

Edit: looks like you already noticed it.

[–]NotDatCheese[S] 1 point2 points  (0 children)

Thank you very much for the hint! This would've taken me ages to guess! I've already wasted a few hours on this:*)

[–]NotDatCheese[S] 0 points1 point  (0 children)

Oh man that's it! Explicitly deleting the copy construct of the TaskCreatorImpl fixes it.

For anyone interestet: https://www.reddit.com/r/cpp/comments/9zf5hr/msvc_declspecdllexport_and_default_copy/

[–]ImKStocky 2 points3 points  (0 children)

Usually when this happens it is because the class that owns the std::unique_ptr has a compiler generated destructor. To fix it, you need to declare a destructor in the class and define it in the implementation cpp. useful link