Search code examples
c++c++11template-meta-programmingenable-if

std::enable_if as single argument of constructor


I'm fairly new to template metaprogramming and have been working through some of the concepts - however, I've been stumped a little by this particular snippet I came across.

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;
};

I had assumed when reading it that it was enabling the default constructor if there were one or more DATATYPES arguments, but having tested it all I got was a compilation error.

I would appreciate any assistance in helping my understanding of this snippet as I understand what enable_if is supposed to be doing but within this context I don't seem to be able to wrap my head around what's actually happening.

EDIT: I guess this is less a question of 'how do I achieve this particular effect?' and more along the lines of 'what is this code actually producing, and does it match up with what I understood to be the intention of the original author?'


Solution

  • std::enable_if is not used correctly if not followed by ::type. std::enable_if<expr> itself is a fairly useless struct type.

    A correct way of conditionally enabling the default constructor:

    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{}
        ) {}
        //...
    };
    

    Live at coliru.