For example, in this code:
#include <iostream>
#include <type_traits>
template<typename T>
requires std::is_same_v<T,int> || std::is_same_v<T,float> || std::is_same_v<T,double>
bool foo(const T& value)
{
return true;
}
template<>
bool foo<double>(const double& value)
{
return false;
}
int main()
{
std::cout << foo(12) << std::endl;
std::cout << foo(1.2f) << std::endl;
std::cout << foo(1.2) << std::endl;
return 0;
}
If I remove the || std::is_same_v<T,double> from the constraint then the third output will fail to compile.
But what I don't understand is why the specialisation can't sort of automatically define it's own constraint? The specialisation itself is indicative that whatever T is it should be a valid type, but now trying to use constraints requires that I "document" all the specialisation ahead of time. Consider a non-toy example where a specialisation does something wildly different, having that specialised type listed in the constraints would be confusing if the fallback version couldn't possible operate on the specialised type.
This seems to me like the compiler could automatically include the specialised types in the list of constraints, because I'm having trouble coming up with a case where a specialised type wouldn't just be considered a new constraint?
I'm hoping someone has an idea of whether this is a technical limitation for the compiler or whether there's another reason the committee decided to do it this way.