Какие типы можно использовать с шаблоном класса concurrency :: task? - PullRequest
0 голосов
/ 21 апреля 2019

Я пытаюсь вернуть пользовательский тип из параллельной среды выполнения задача . Мой пользовательский тип должен быть конструируемым только через статический фабричный метод (кроме конструируемого при перемещении), например ::1003

#include <utility>

struct foo
{
    foo() = delete;
    foo(foo const&) noexcept = delete;
    foo& operator=(foo const&) noexcept = delete;

    foo(foo&&) noexcept = default;
    foo& operator=(foo&&) noexcept = default;

    static foo make_foo(int const value) noexcept { return std::move(foo{ value }); }

private:
    foo(int const) noexcept {}
};

И простой тестовый пример:

#include <ppltasks.h>
using namespace concurrency;

int main()
{
    auto&& task
    {
        create_task([value = 42]()
        {
            return foo::make_foo(value);
        })
    };
    auto&& result{ task.get() };
}

Это, однако, не компилируется, производя следующую (сокращенную) диагностику компилятора:

ppltasks.h(644,1): error C2280:  'foo::foo(const foo &) noexcept': attempting to reference a deleted function
main.cpp(223): message :  see declaration of 'foo::foo'
main.cpp(223,5): message :  'foo::foo(const foo &) noexcept': function was explicitly deleted

Здесь нет ничего удивительного, copy-c'tor действительно явно удален специально. Я просто не понимаю, почему конструктор ходов не считается кандидатом.

Кажется, что я могу получить код для компиляции, если я предоставлю оператор по умолчанию, оператор копирования и оператор назначения копирования. Это ограничение библиотеки (ConcRT), компилятора (Visual Studio 2019 16.1.0), языка программирования или моего контроля над ним?

По-другому: могу ли я что-нибудь сделать, чтобы мой пользовательский тип (как он есть) играл вместе с concurrency::task, или требования к конструктивности по умолчанию, конструктивности копирования и назначению копирования недокументированы?

...