std::enable_if как единственный аргумент конструктора
Я довольно новичок в шаблонном метапрограммировании и прорабатывал некоторые концепции - однако, этот фрагмент кода, с которым я столкнулся, немного озадачил меня.
template<class TAG, typename... DATATYPES>
struct Message {
Message (typename std::enable_if<sizeof...(DATATYPES) >= 1>) {
}
... (various other constructor declarations here)
std::tuple<DATATYPES...> m_data;
};
Когда я читал его, я предполагал, что он включал конструктор по умолчанию, если был один или несколько аргументов DATATYPES, но протестировав его, я получил только ошибку компиляции.
Я был бы признателен за любую помощь в понимании этого фрагмента, так как я понимаю, что должен делать enable_if, но в этом контексте мне кажется, что я не могу понять, что на самом деле происходит.
РЕДАКТИРОВАТЬ: я думаю, это не вопрос "как мне добиться этого конкретного эффекта?" и еще по линии "что на самом деле производит этот код, и соответствует ли он тому, что я понимал как намерение первоначального автора?"
2 ответа
std::enable_if
не используется правильно, если не сопровождается ::type
, std::enable_if<expr>
сам по себе довольно бесполезный struct
тип.
Правильный способ условного включения конструктора по умолчанию:
template<class TAG, typename... DATATYPES>
struct Message {
private:
struct dummy_type {};
public:
template <typename T = std::tuple<DATATYPES...>>
Message(
typename std::enable_if<std::tuple_size<T>() >= 1, dummy_type>::type
= dummy_type{}
) {}
//...
};
Подписи функций-членов являются частью определения класса и должны быть разрешены при создании экземпляра класса. Это означает, что компилятор пытается enable_if
тоже, и если условие не выполнено, обнаруживается, что оно не имеет вложенного type
ошибка.
Чтобы заставить SFINAE работать, вам нужно сделать конструктор шаблоном и иметь enable_if
зависит от параметра шаблона. Смотрите ответ @acheplers для примера.
То, что делает код в OP, является странным способом утверждения размера DATATYPE
пакет, который будет сделан с static_assert
гораздо понятнее. Или, может быть, автор просто не знал, как правильно делать SFINAE.