Почему специализация и шаблон не совпадают? - PullRequest
0 голосов
/ 07 августа 2020

Я новичок в шаблонах C ++. Это пример кода, который я написал для тестирования сотрудников std::enable_if_t. Но он не компилируется со следующей ошибкой:

No function template matches function template specialization 'print'
Candidate template ignored: couldn't infer template argument 'T'

Что я делаю не так?

#include <string>
#include <type_traits>

class IPoint
{
public:
   IPoint()
      : x(0), y(0)
   {}

   IPoint(int xValue, int yValue)
      : x(xValue), y(yValue)
   {}

public:
   int x;
   int y;
};

namespace utils
{
   template<typename T>
   typename std::enable_if_t<true, T> print(const std::string& s) 
   {
      return 0;
   }

   template<>
   inline IPoint print(const std::string& s)
   {
      return IPoint(0, 0);
   }
}

1 Ответ

3 голосов
/ 07 августа 2020

Прежде всего, вы смешиваете SFINAE со специализацией функции . Так не пойдет. Вам нужно выбрать один.

Во-вторых, включить if всегда true, поэтому он будет всегда выбран, независимо от того, что это за T.

std::enable_if_t<true, T>
//               ^^^^

Вам нужен следующие (в ) для работы SFINAE:

#include <type_traits> // std::is_same

namespace utils
{
   template<typename T>
   typename std::enable_if<!std::is_same<IPoint, T>::value, T>::type // T != IPoint 
      print(const std::string& s)
   {
      return 0;
   }

   template<typename T>
   typename std::enable_if<std::is_same<IPoint, T>::value, T>::type   // T == IPoint 
      print(const std::string& s)
   {
      return IPoint(0, 0);
   }
}

В качестве примечания, в это будет сокращено до одной единственной функции шаблона с использованием if constexpr

namespace utils
{
   template<typename T>
   auto print(const std::string& s) 
   {
      if constexpr (std::is_same<IPoint, T>::value)
         return IPoint(0, 0);
      else
         return 0;
   }
}
...