I learnt about the SFINAE principle and its various uses. Then I wrote the following program that compiles with gcc but not with msvc and clang. Live demo.
#include <iostream>
#include <type_traits>
template <typename T> class Container {
public:
template<typename U = T>
std::enable_if_t<std::is_same_v<T, int>> foo(const T&)
{
}
};
template<typename T>
void func(T&& callable)
{
Container<int> c;
(c.*callable)(4);
}
int main(){
//works with gcc but not with clang and msvc
func(&Container<int>::foo);
}
As we can see the above program works with gcc but not with clang and msvc and I don't know which compiler is right here. So is this program well-formed or ill-formed etc.
enable_if
. Change it tovoid
and you should get the same errors. – Wingofoo<int>
at the point where a pointer to thefoo
is taken. Also, it's either member functions are automatically "skipped" when not used so you don't need to disable them, or there are more than one such function and all-but-one are disabled for each "taking of a pointer", but then you still have to disambiguate somehow which function you're interested in when taking a pointer to it. Do you have a use-case? – Veeryenable_if
usage is wrong: instantiatingContainer<char>
would produce hard error, you needstd::enable_if_t<std::is_same_v<U, int>>
. In C++20, arequires(std::is_same_v<T, int>)
(and remove the template) would simplify things. – Aloke