I'm trying to understand two different versions of a template function that uses std::enable_if<>.
Version 1:
template<class T, typename std::enable_if<std::is_convertible<T, std::string_view>::value, T>::type* = nullptr>
void foo(const T& msg);
Version 2:
template<class T, typename = typename std::enable_if<std::is_convertible<T, std::string_view>::value>::type>
void foo(const T& msg);
If I understood it correctly, if the condition is met they should be converted into:
// Version 1
template<class T, T* = nullptr>
void foo(const T& msg);
// Version 2
template<class T, typename = void>
void foo(const T& msg);
Both versions can be equally called by:
std::string s = "Test";
foo(s);
What is the difference between those two versions? When should one be used?
Second question
Because of an error on my part, I discovered that version 2 also compiles, if one typename is missing:
//Correct Version 2 like above:
template<class T, typename = typename std::enable_if<std::is_convertible<T, std::string_view>::value>::type>
void foo(const T& msg);
// My "faulty" version, also works. Is this correct too?
template<class T, typename = std::enable_if<std::is_convertible<T, std::string_view>::value>::type>
void foo(const T& msg);
Is the second (faulty) version also correct? I thought std::enable_if<> does need a typename in front of it.