Я пишу платформу 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. Это все еще возможно?