Это поведение определено стандартом, и, насколько я могу судить, gcc
здесь корректно, если мы посмотрим на проект C ++ standard section 13.1
Перегружаемые объявления paragraph 3 говорит:
[...] - объявления параметров, которые отличаются только наличием или отсутствием константы и / или летучих, эквивалентны. То есть, константные и неустойчивые типы-спецификаторы для каждого типа параметра игнорируются при определении того, какая функция объявляется, определяется или вызывается.
blockquote>и предоставляет этот пример:
[ Example: typedef const int cInt; int f (int); int f (const int); // redeclaration of f(int) int f (int) { /* ... */ } // definition of f(int) int f (cInt) { /* ... */ } // error: redefinition of f(int) —end example ]
и некоторые подробности, поясняющие, что это относится только к внешним cv квалификаторам ( ] emphasis mine ):
Только конструкторы типа const и volatile на самом внешнем уровне спецификации типа параметра игнорируются таким образом; const и volatile, специфицированные по типу спецификаций параметров, являются значительными и могут использоваться для различения перегруженных деклараций функций.123 В частности, для любого типа T, «указатель на T», «указатель на const T» и «указатель на volatile T "считаются отдельными типами параметров, как« ссылка на T »,« ссылка на const T »и« ссылка на volatile T. »
blockquote>, и насколько я могу судить это относится и к функциям шаблона в классах шаблонов, а также из раздела
14.8
Специализация шаблонов функций , в частности14.8.3
Разрешение перегрузки , которое гласит:[...] Полный набор функций-кандидатов включает в себя все синтезированные объявления и все перегруженные функции без шаблона с тем же именем. Синтезированные объявления обрабатываются как любые другие функции в остальной части разрешения перегрузки, за исключением случаев, явно указанных в 13.3.3.144
blockquote>