Как я могу определить время компиляции, если у класса есть конструктор с данной сигнатурой? Чтобы быть конкретным, я хотел бы сделать следующее:
class Archive
{
// (...)
template <typename T>
T Read()
{
if constexpr(HasUnarchiveConstructor<T>())
{
return T(*this); // constructor accepts reference to Factory
}
else
{
T t;
Unarchive(*this, t); // use stand alone function instead. (if this is not available either, compiling fails)
return t;
}
}
}
Существует множество источников для обнаружения функций с определенными сигнатурами. Однако я не могу преобразовать их в конструкторы. источник 1 источник 2 источник 3 и другие.
Из найденных источников я скомпилировал следующее, чтобы определить, есть ли у функции оператор плюс:
template<typename T>
using HasUnarchiveConstructorImpl = decltype(std::declval<T>() + std::declval<T>());
template< typename T >
using HasUnarchiveConstructor = std::is_detected<HasUnarchiveConstructorImpl, T>;
Как я могу распространить это на проверку, которую я хочу выполнить? Или как я могу сделать это по-другому?
2 ответа
Как я могу распространить это на проверку, которую я хочу выполнить?
Вы можете использовать decltype(...)
в выражении T{...}
следующим образом:
struct Foo
{
Foo(Archive&) { }
};
struct Bar
{
// unsupported
};
template<class T>
using HasUnarchiveConstructorImpl =
decltype(T{std::declval<Archive&>()});
template <class T>
using HasUnarchiveConstructor =
std::experimental::is_detected<HasUnarchiveConstructorImpl, T>;
static_assert(HasUnarchiveConstructor<Foo>::value);
static_assert(!HasUnarchiveConstructor<Bar>::value);
Или как я могу сделать это по-другому?
Я хотел бы использовать:
if constexpr(std::is_constructible<T, Archive&>{})
Эта черта живет в <type_traits>
и поставляется готовой и отлаженной для вас. Существует целое семейство черт, чтобы обнаружить варианты этого вопроса, доступные для вас там.
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который будет скомпилирован с помощью компилятора C ++). Используйте тег, зависящий от версии, для вопросов, связанных с конкретной редакцией стандарта [C ++ 11], [C ++ 14], [C ++ 17] или [C ++ 20] и т. Д.