Возврат шаблона с указателем на функцию - PullRequest
0 голосов
/ 09 января 2019

У меня ранее не работал код при переходе с g ++ - 5 на g ++ - 6; ранее выводимый шаблон больше не выводимый. Минимальный пример:

#include <math.h>

template<typename T,typename T1>
T apply(T (*func)(T1), const T1 &val)
{
  return func(val);
}

int main(void)
{
  double val1 = 0.5, val2 = apply(ceil,val1);
  return 0;
}

g ++ - 6 не может найти правильную версию ceil:

foo.cpp: In function ‘int main()’:
foo.cpp:11:44: error: no matching function for call to ‘apply(<unresolved overloaded function type>, double&)’
   double val1 = 0.5, val2 = apply(ceil,val1);
                                        ^
foo.cpp:4:3: note: candidate: template<class T, class T1> T apply(T (*)(T), const T1&)
 T apply(T (*func)(T), const T1 &val)
   ^~~~~
foo.cpp:4:3: note:   template argument deduction/substitution failed:
foo.cpp:11:44: note:   couldn't deduce template parameter ‘T’
   double val1 = 0.5, val2 = apply(ceil,val1);

g ++ - 5 не имеет проблем и работает как положено. Используя Compiler Explorer с g ++ 8 на https://godbolt.org/z/oBSopG, я также вижу возврат от clang-3.3 (компилируется) к clang-3.4 (не компилируется).

Учитывая, что код по-прежнему не работает, даже в текущем g ++, я предполагаю, что ошибка с моей стороны. Что я сделал не так и как я могу это исправить?

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Если вы используете (или планируете использовать) C ++ 17, вы должны знать, что есть более надежная библиотечная функция, выполняющая то, что вы пытаетесь сделать: std :: invoke

С его помощью ваш пример может быть уменьшен до:

#include <cmath>
#include <functional>

int main(void)
{
  double val1 = 0.5, val2 = std::invoke(ceil,val1);
  return 0;
}

Интересно, что и с вашей ручной apply, и с библиотекой std::invoke код не будет работать, если вы напишите std::invoke(std::ceil, val1). Это требует дальнейшего расследования ....

0 голосов
/ 09 января 2019

Что я сделал не так и как я могу это исправить?

Способ исправить это #include <cmath> вместо использования #include <math.h>, как указано в справочной документации :

#include <cmath> // <<< official header to use.
#include <iostream>

template<typename T,typename T1>
T apply(T (*func)(T1), const T1 &val)
{
  return func(val);
}

int main(void)
{
  double val1 = 0.5, val2 = apply(ceil,val1);

  std::cout << val1 << ' ' << val2<< std::endl;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...