Почему с точки зрения компилятора это 3 разных типа?
В стандарте ничего внятного по этому поводу нет (ну или я не смог найти) и почему это касается только (s/u) char (в чем так сказать причина)?
То что это 3 разных типа говорит нам:
std::cout << std::is_same<signed char, char>::value << std::endl; << false
std::cout << std::is_same<unsigned char, char>::value << std::endl; << false
Более того, будет сгенрировано 2 одинаковых копии метода A<char / signed char>::foo()
https://godbolt.org/g/GhGMJS