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.

Другие вопросы по тегам