0

In following code, could anyone explain why do I get following error: "error: no type named ‘type’ in struct std::enable_if<false, double>

According to my understanding of enable_if_t, there should not be any problem at compile time if I am not using function p. It should simply not get generated for simple types.

But when I change condition to !is_class_v<T>, it works fine for simple types but then it stops working for class types.

template<typename T>
class Smart_class
{
    public:        
        enable_if_t<is_class_v<T>, T> p(T t)
        {            
            
        };
};

void f()
{
    Smart_class<double> a;
}
virus00x
  • 713
  • 5
  • 12
  • 3
    Possibly relevant question: [Why doesn't SFINAE (enable_if) work for member functions of a class template?](https://stackoverflow.com/q/30953248/580083). – Daniel Langr Aug 18 '20 at 06:55
  • @DanielLangr this is so common mistake, that there should be some catch-phrase for it. Something like "Declaration is not substitution" – Swift - Friday Pie Aug 18 '20 at 07:09
  • Thanks Daniel Langr. I understood the cause. – virus00x Aug 18 '20 at 07:17
  • @Swift-FridayPie I don't think this is a duplicate. That question asked why SFINAE does not work as expected. Here, the problem is somewhere else — that the declaration of `p` is instantiated. – Daniel Langr Aug 18 '20 at 07:21
  • @Daniel Langr the only point of `enable_if_t` is to prevent substitution to happen. but at context of function declaration substitution already happened when class was implicitly instantiated and results in syntax error (there is no nested definition in `enable_if` present). if "p" itself was a template, that won't happen. That's essentially is a failed attempt to use SFINAE, it looks like `p` was meant for types that are classes only – Swift - Friday Pie Aug 18 '20 at 07:24
  • @Swift-FridayPie I understand your point. Just based on this sentence: _"According to my understanding of `enable_if_t`, there should not be any problem at compile time if I am not using function `p`."_ — I think the OP asked about something else. – Daniel Langr Aug 18 '20 at 07:39

1 Answers1

1

Quoting from temp.inst/3.1:

The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions, of the non-deleted class member functions...

This is your case, the declaration of p member function is instantiated and it refers to the non-existing return type.

Daniel Langr
  • 22,196
  • 3
  • 50
  • 93