Подтвердить что ты не робот

Почему С++ выводит аргументы шаблона в правой части оператора присваивания с левой стороны?

template <typename T>
void func(T&){
}

int main(){
    void (*p)(int&) = func;//or &func
    return 0;
}

Интересно, почему этот код компилируется (с g++). Кажется, аргумент функции шаблона выводится из типа p? Это стандартное поведение?

Изменить: Я придумал возможное объяснение. Это присваивание имеет подпись:

void(*&)(int&)operator=(void(*)(int&));

Таким образом, func фактически выводится из входного аргумента типа operator =, а не из типа p напрямую. Это правильно?

4b9b3361

Ответ 1

Это стандартное поведение?

Да, это так. Вывод аргумента шаблона также происходит, когда вы берете адрес шаблона функции (например, при назначении или инициализации указателя функции). Это явно разрешено в [temp.deduct.funcaddr]/1:

Аргументы шаблона могут быть выведены из типа, указанного при принятии адрес перегруженной функции. Шаблон функции тип функции и указанный тип используются как типы P и A, и вывод выполняется, как описано в [temp.deduct.type].

Тип указателя функции предоставляет аргумент (A в предыдущем абзаце).

Таким образом, func фактически выводится из входного аргумента типа operator =, а не из типа p напрямую. Это правильно?

Не совсем. Во-первых, это не назначение, это инициализация, которую вы делаете. И даже если бы он использовал перегруженную функцию operator=, вам нужно было бы вывести для инициализации аргумента для оператора присваивания, который вернет вас к квадрату.