Применяется ли для размещения C ++ 17 копия? - PullRequest
2 голосов
/ 21 марта 2020

Я пишу универсальный c интерфейс для языков сценариев, и мне нужно вызывать функции, которые возвращают объект и помещают полученный объект в пространство, предоставляемое языком сценариев. Я протестировал clang ++ на ОС Ma c, и, похоже, следующее делает возможным копирование / перемещение:

class T {
public:
    T() {}
    T(const T &t) {
        std::cout << "Copy" << std::endl;
    }
    T(T&&t) : x(t.x) {
        std::cout << "Move" << std::endl;
    }
private:
    int x = 3;
};

T h()
{
    return T();
}

void buildTInto(void *p)
{
    new (p) T(h());
}

int main(int argc, char *argv[])
{
    alignas(T) char space[sizeof(T)];
    buildTInto(space);
}

Запуск этого кода ничего не печатает. Чтение справочного описания cpp elision , по-видимому, указывает на то, что это правильное поведение, учитывая приведенный ими пример, который вызывает только один конструктор:

T x = T(T(f())); // only one call to default constructor of T, to initialize x

Я думаю, что мой код очень похоже на то, что без исключения копирования будет вызван конструктор ходов (точно так же, как T(T(f())) вызовет конструкцию двух ходов).

Не будучи юристом спец c, мне любопытно, если мое понимание правильно, и мне интересно, все ли C ++ 17-совместимые компиляторы делают это правильно?

1 Ответ

1 голос
/ 21 марта 2020

Гарантированное разрешение (также известное как C ++ 17 для определения значений ) применяется к инициализации любого объекта типа T с значением типа того же типа. Сюда входят объекты, созданные с помощью new выражений, включая размещение new форм.

Действительно, вам даже не нужно повторять тип в момент вызова выражения new: new(p) auto(h()); обеспечивает обязательное условие гарантированного исключения.

...