Вызов конструктора типа шаблона, только если он существует в C ++ - PullRequest
0 голосов
/ 29 апреля 2020

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

Проблема в том, что я хочу различать объекты, которые могут быть агрегированы-инициализированы или инициализируется через их конструктор. Я знаю, как проверить, является ли объект конструируемым, используя черту типа std::is_constructible. Тем не менее, когда я пытаюсь использовать его, он не может скомпилировать. Ниже приведен короткий фрагмент соответствующего кода. Обратите внимание, что до этого существуют другие процедуры, которые обрабатывают проверку ошибок и управление пулом массивов, но я думаю, что они не имеют значения.

template <typename ... Fields>
void add_component(Fields ... params) {
    if(std::is_constructible<Component, Fields ...>::value) {
        std::cout << "Yes!\n";
        pool_[length_] = Component(params ...);
    }
    else {
        std::cout << "No\n";
        pool_[length_] = {params ...};
    }
    length_++;
}

Я ясно вижу, что std::is_constructible правильно идентифицирует объекты, которые могут быть построены , но он все еще пытается вызвать конструктор во время компиляции. Например:

struct Vec2D {
    float x, y;
};

Если я пытаюсь добавить компонент Vec2D к моей сущности, он выдаст мне следующую ошибку:

error: no matching function for call to ‘Dynamo::Vec2D::Vec2D(float&, float&)’
  122 |                 pool_[length_] = Component(params ...);
      |                                  ^~~~~~~~~~~~~~~~~~~~~
In file included from src/main/../core/display.h:9,
                 from src/main/scene.h:9,
                 from src/main/engine.h:10,
                 from src/Dynamo.h:4,
                 from main.cpp:1:
src/main/../core/../util/vector.h:11:12: note: candidate: ‘Dynamo::Vec2D::Vec2D()’
   11 |     struct Vec2D {
      |            ^~~~~
src/main/../core/../util/vector.h:11:12: note:   candidate expects 0 arguments, 2 provided
src/main/../core/../util/vector.h:11:12: note: candidate: ‘constexpr Dynamo::Vec2D::Vec2D(const Dynamo::Vec2D&)’
src/main/../core/../util/vector.h:11:12: note:   candidate expects 1 argument, 2 provided
src/main/../core/../util/vector.h:11:12: note: candidate: ‘constexpr Dynamo::Vec2D::Vec2D(Dynamo::Vec2D&&)’
src/main/../core/../util/vector.h:11:12: note:   candidate expects 1 argument, 2 provided

Я ожидаю, что метод агрегирует-инициализирует компонент, но он все еще пытается вызвать конструктор. Что здесь не так? Возможно, что-то не так с тем, как я использовал шаблоны?

Редактировать: Мне известно о if constexpr(), но я ищу решение, которое могло бы работать с версиями компилятора до C ++ 17. Это все еще возможно?

...