На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Специализация шаблона с std::function
    ExpandedWrap disabled
      #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
      Что-то я уже запамятовал такие детали.
      Тут нет специализаций, тут перегрузка. Сначала компилятор применяет к шаблонам вывод параметров и получает конкретизированные сигнатуры, затем пытается разрешить перегрузку. По первой функции fn совпадает строго, а TT выводится как {int}; по второй T выводится как std::function<void(int)>, func как int, а TT как {}. В обоих случаях имеет место точное соответствие для всех параметров, и вся разница только в эллипсисах. Однако первая функция более специализирована, но имеет эллипсис во втором параметре, а вторая имеет эллипсис в третьем (и его список в данном случае пуст), но менее специализирована по первому параметру, так что я бы предпочёл тут диагностику о неоднозначности.
      Если добавить к первой функции вторым параметром T&& между fn и ...args, должно помочь, т.к. эллипсиссы будут на одинаковых местах, и бо́льшая специализация по первому параметру должна начать работать.
      Сообщение отредактировано: Qraizer -
        Цитата Qraizer @
        Если добавить к первой функции вторым параметром T&& между fn и ...args, должно помочь, т.к. эллипсиссы будут на одинаковых местах, и бо́льшая специализация по первому параметру должна начать работать.

        Да, так и есть. http://ideone.com/z3cuSB
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0270 ]   [ 17 queries used ]   [ Generated: 20.04.24, 02:28 GMT ]