简体   繁体   中英

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?'

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.

Member function signatures are a part of class definition and need to be resolved when the class is instantiated. This means that compiler tries enable_if , too, and if the conditon is not fullfilled, it discovers that it doesn't have the nested type - hard error.

To make SFINAE work, you need to make the constructor a template and have enable_if depend on a template parameter. See @acheplers's answer for example.

What the code in OP does is a weird way of asserting the size of DATATYPE pack, which would be done with static_assert much more clearly. Or, maybe the author just didn't know how to do SFINAE correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM