Ответ 1
Если я правильно понимаю, это означает, что нет такой вещи, как функция, не являющаяся членом-константой. (Хотя такие функции не являются константами, они не могут быть изменены согласно 3.10/6). В частности, указатели на функцию const не имеют смысла.
Да, нет функции типа const
, и попытки создать ее игнорируются из-за того же самого параграфа, который вы указали. Это важно, потому что программа, которая каким-либо образом создает тип функции const
, не плохо сформирована (как это было в С++ 03); просто его попытка игнорируется, и вместо него рассматривается тип функции не const
.
Вероятно, что GCC и ICC не применяются, потому что, когда перегрузка не const
удалена, программа не компилирует:
#include <iostream>
void f() {}
template <typename T> void g( T const*)
{
std::cout << "const " << std::endl;
}
int main() {
g(f); // ERROR with GCC and ICC, compiles with Clang
}
Относительно вашей интерпретации:
При компиляции с GCC и Intel код выводит "non const", как я ожидал бы из приведенной выше цитаты. Однако при компиляции с Clang и Visual Studio вывод "const". Является ли моя интерпретация правильной?
Я так не верю. Насколько я могу судить, Кланг прав.
Этот вывод основан на том, что оба функциональных шаблона жизнеспособны, потому что const
квалификаторы игнорируются в типах функций, а один более специализирован, чем другой.
В соответствии с параграфом 8.3.5/7 стандарта С++ 11:
[...] Эффект cv-qualifier-seq в объявлении функции не совпадает с добавлением cv-qualification сверху типа функции. В последнем случае cv-квалификаторы игнорируются. [...]
Это эффективно делает второй шаблон функции жизнеспособным для разрешения вызова (первый, очевидно, есть). Но поскольку оба функциональных шаблона жизнеспособны, вступает в игру пункт 13.3.3.1 о разрешении перегрузки:
Учитывая эти определения, жизнеспособная функция F1 определена как лучшая функция, чем другая жизнеспособная функция F2, если для всех аргументов я ICSi (F1) не является худшей последовательностью преобразования, чем ICSi (F2), а затем
- для некоторого аргумента j ICSj (F1) является лучшей последовательностью преобразования, чем ICSj (F2), или, если не это,
- контекст представляет собой инициализацию путем пользовательского преобразования (см. 8.5, 13.3.1.5 и 13.3.1.6) и стандартная последовательность преобразования из возвращаемого типа F1 в тип назначения (т.е. тип инициализация объекта) является лучшей последовательностью преобразования, чем стандартная последовательность преобразования из тип возврата F2 к типу назначения. [...] или, если не это,
- F1 - это не шаблонная функция, а F2 - специализированная функция шаблона или, если не это,
- F1 и F2 являются специализированными шаблонами функций, а шаблон функции для F1 более специализирован, чем шаблон для F2 в соответствии с правилами частичного упорядочения, описанными в 14.5.6.2.
Поскольку второй шаблон функции более специализирован, чем первый, второй шаблон функции должен быть выбран с помощью разрешения перегрузки. Поэтому Кланг прав.