Как вызвать конструктор копирования, только если он существует?C ++ - PullRequest
0 голосов
/ 21 ноября 2018

Я делаю Entity-Component-System Engine и у меня небольшие проблемы с префабами.Я хочу скопировать префаб, только если класс, который передал пользовательский шаблон, является копируемым.Простая реализация того, что я хочу сделать, будет выглядеть примерно так:

void addFromPrefab() { //We assume that _prefab is of type std::shared_ptr<T>
    if (std::is_copy_constructible<T>::value)
        addComponent(*_prefab); // Add a new component by copy constructing the prefab passed as parameter
    else if (std::is_default_constructible<T>::value)
        addComponent(); // Add a new component with his default constructor
    else
        throw std::exception();
}

template<typename ...Args>
void addComponent(Args &&...args) {
    store.emplace_back(std::make_shared<T>(args ...));
}

Есть ли способ заставить этот код работать?На самом деле, мне кажется, что он не может создать определенный класс, потому что удаляется конструктор, который может быть скопирован.)

1 Ответ

0 голосов
/ 21 ноября 2018

Если у вас есть C ++ 17, используйте if constexpr:

void addFromPrefab() { //We assume that _prefab is of type std::shared_ptr<T>
    if constexpr(std::is_copy_constructible<T>::value)
        addComponent(*_prefab); // Add a new component by copy constructing the prefab passed as parameter
    else if constexpr(std::is_default_constructible<T>::value)
        addComponent(); // Add a new component with his default constructor
    else
        throw std::exception();
}

Если у вас нет, вы должны использовать SFINAE:

std::enable_if<std::is_copy_constructible<T>::value> addFromPrefab() { //We assume that _prefab is of type std::shared_ptr<T>
    addComponent(*_prefab); // Add a new component by copy constructing the prefab passed as parameter
}
std::enable_if<!std::is_copy_constructible<T>::value && std::is_default_constructible<T>::value> addFromPrefab() {
    addComponent(); // Add a new component with his default constructor
}

std::enable_if<!std::is_copy_constructible<T>::value && !std::is_default_constructible<T>::value> addFromPrefab() {
        throw std::exception();
}
...