C ++ не копируемая лямбда ведет себя как копируемая? - PullRequest
10 голосов
/ 12 апреля 2019

Почему следующий код компилируется?

#include <memory>
#include <vector>

int main()
{
    std::vector<std::unique_ptr<int>> uncopyableStuff;
    for(int i = 0; i < 5; ++i)
        uncopyableStuff.emplace_back(std::make_unique<int>(i));
    auto lambda = [uncopyableStuff = std::move(uncopyableStuff)](){};
    static_assert(std::is_copy_constructible<decltype(lambda)>::value);
}

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

auto copy = lambda;

Это дает мнеошибка компиляции (как я и ожидал).Есть ли какие-то исключения для черт лямбды и черты конструктивности копирования?

См. Ссылку для примера Godbolt: https://godbolt.org/z/GByclH

РЕДАКТИРОВАТЬ:

Как правильно определить, является лиЛямбда будет компилироваться при попытке копирования.Я не интересуюсь теоретической конструкцией копии данного вызываемого объекта, но обнаруживаю успешную конструкцию копии.Мне все еще кажется очень странным, что конструктор векторных копий определен таким образом.

1 Ответ

6 голосов
/ 12 апреля 2019

Есть ли какое-то исключение для черт лямбда и копируемости?

Нет. Если вы протестируете std::is_copy_constructible<std::vector<std::unique_ptr<int>>>::value, вы обнаружите, что это также верно.

Причина в том, что std::vector имеет доступный и не удаляемый конструктор копирования, даже если тип элемента не может быть скопирован. Если создается экземпляр конструктора копирования, он не сможет скомпилироваться, но это находится за пределами непосредственного контекста и поэтому не может быть обнаружено чертой std::is_copy_constructible.

Может быть заманчиво сделать конструктор копирования std::vector SFINAE для конструктивности копирования типа элемента, но я полагаю, что это нарушит тип, который хранит вектор самого типа в качестве члена: struct Node { std::vector<Node> children; }, поскольку в этом случае конструктивность копирования Node и std::vector<Node> будет взаимозависимой.

...