Итак, у меня есть эта часть рекурсивного шаблона класса. Я протестировал его в обычном проекте Visual Studio, и он работает точно так же, как и ожидалось.
// emplace_back using a single argument to copy-construct the object.
template <typename FirstType, typename... RestTypes>
typename std::enable_if<std::is_copy_constructible<FirstType>::value, void>::type inline emplace_back(const FirstType& first, RestTypes&& ... rest) {
new (&mydata[this->mysize]) FT(first);
_structofarrays_base<RTs...>& base = *this;
base.emplace_back(rest...);
}
// emplace_back using a single argument to move-construct the object.
template <typename FirstType, typename... RestTypes>
typename std::enable_if<std::is_move_constructible<FirstType>::value, void>::type inline emplace_back(FirstType&& first, RestTypes&&... rest) {
new (&mydata[this->mysize]) FT(std::move(first));
_structofarrays_base<RTs...>& base = *this;
base.emplace_back(rest...);
}
// emplace_back using no arguments to construct the object.
template <typename... RestTypes>
inline void emplace_back(decltype(std::ignore), const RestTypes& ... rest) {
new (&mydata[this->mysize]) FT();
_structofarrays_base<RTs...>& base = *this;
base.emplace_back(rest...);
}
// emplace_back using multiple arguments to construct the object.
template <typename... FirstTypes, typename... RestTypes>
inline void emplace_back(const std::tuple<FirstTypes...>& first, const RestTypes& ... rest) {
std::apply([=](const FirstTypes& ... args) {new (&mydata[this->mysize]) FT(args...); }, first);
_structofarrays_base<RTs...>& base = *this;
base.emplace_back(rest...);
}
Однако, когда я перемещаю код в проект Visual Studio CMake, неожиданно возникает следующая ошибка: ...\structofarrays.hpp(345): error C2440: 'initializing': cannot convert from 'const FirstType' to 'FT' with [ FirstType=std::_Ignore ] and [ FT=short ]
По сути, я пытаюсь использовать std::ignore
в качестве аргумента, который должен заставить его использовать третью версию функции (конструктор по умолчанию), но вместо этого он пытается использовать первую версия (конструктор копирования), и, очевидно, она не может конвертировать std::ignore
в короткий. То же самое происходит, когда я пытался использовать аргумент std::tuple
; вместо использования правильной четвертой функции она использует вторую (конструктор перемещения).
Меня смущает то, что это работало точно так, как ожидалось в обычном проекте Visual Studio, и перестало работать, когда я переключился на проект CMake. Что здесь происходит?
Я использую Visual Studio 2019 и C ++ 17.
РЕДАКТИРОВАТЬ: изменение генератора с «ниндзя» на «Visual Studio 16 2019» не исправляет выпуск.