Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.117.142.128] |
|
Сообщ.
#1
,
|
|
|
#include <iostream> #include <functional> template <typename... TT> void Invoke(std::function<void(int)> &fn, TT&&... args) { //fn(std::forward<TT>(args)...); } template <typename T, typename TFunc, typename... TT> void Invoke(T &obj, TFunc &&func, TT&&... args) { //func(std::forward<TT>(args)..., obj); std::cout << __PRETTY_FUNCTION__ << std::endl; } int main() { std::function<void(int)> fn = [](int n) { }; Invoke(fn, 1); return 0; } Почему компилятор выбирает именно void Invoke(T &obj, TFunc &&func, TT&&... args)? Т.е. в данном случае на экран выводится строчка "void Invoke(T&, TFunc&&, TT&& ...) [with T = std::function<void(int)>; TFunc = int; TT = {}]". Если первый вариант Invoke объявить как void Invoke(std::function<void(int)> &fn, int), то всё отрабатывает правильно. Компилятор - gcc 6.3.0 |
Сообщ.
#2
,
|
|
|
Что-то я уже запамятовал такие детали.
Тут нет специализаций, тут перегрузка. Сначала компилятор применяет к шаблонам вывод параметров и получает конкретизированные сигнатуры, затем пытается разрешить перегрузку. По первой функции fn совпадает строго, а TT выводится как {int}; по второй T выводится как std::function<void(int)>, func как int, а TT как {}. В обоих случаях имеет место точное соответствие для всех параметров, и вся разница только в эллипсисах. Однако первая функция более специализирована, но имеет эллипсис во втором параметре, а вторая имеет эллипсис в третьем (и его список в данном случае пуст), но менее специализирована по первому параметру, так что я бы предпочёл тут диагностику о неоднозначности. Если добавить к первой функции вторым параметром T&& между fn и ...args, должно помочь, т.к. эллипсиссы будут на одинаковых местах, и бо́льшая специализация по первому параметру должна начать работать. |
Сообщ.
#3
,
|
|
|
Цитата Qraizer @ Если добавить к первой функции вторым параметром T&& между fn и ...args, должно помочь, т.к. эллипсиссы будут на одинаковых местах, и бо́льшая специализация по первому параметру должна начать работать. Да, так и есть. http://ideone.com/z3cuSB |