std::enable_if to conditionally compile a member function

前端 未结 7 2240
执笔经年
执笔经年 2020-11-22 04:57

I am trying to get a simple example to work to understand how to use std::enable_if. After I read this answer, I thought it shouldn\'t be too hard to come up wi

7条回答
  •  感动是毒
    2020-11-22 05:32

    SFINAE only works if substitution in argument deduction of a template argument makes the construct ill-formed. There is no such substitution.

    I thought of that too and tried to use std::is_same< T, int >::value and ! std::is_same< T, int >::value which gives the same result.

    That's because when the class template is instantiated (which happens when you create an object of type Y among other cases), it instantiates all its member declarations (not necessarily their definitions/bodies!). Among them are also its member templates. Note that T is known then, and !std::is_same< T, int >::value yields false. So it will create a class Y which contains

    class Y {
        public:
            /* instantiated from
            template < typename = typename std::enable_if< 
              std::is_same< T, int >::value >::type >
            T foo() {
                return 10;
            }
            */
    
            template < typename = typename std::enable_if< true >::type >
            int foo();
    
            /* instantiated from
    
            template < typename = typename std::enable_if< 
              ! std::is_same< T, int >::value >::type >
            T foo() {
                return 10;
            }
            */
    
            template < typename = typename std::enable_if< false >::type >
            int foo();
    };
    

    The std::enable_if::type accesses a non-existing type, so that declaration is ill-formed. And thus your program is invalid.

    You need to make the member templates' enable_if depend on a parameter of the member template itself. Then the declarations are valid, because the whole type is still dependent. When you try to call one of them, argument deduction for their template arguments happen and SFINAE happens as expected. See this question and the corresponding answer on how to do that.

提交回复
热议问题