首页 > 解决方案 > 用于模板类中的同名函数时,std::enable_if 会产生错误

问题描述

问题描述

我正在尝试调用一个返回12取决于类型是signed char还是的函数unsigned int

为此,我编写了以下代码。如果我在没有main. 我没有编译错误。

但是,当我使用 object 的实例化编译代码时Coverage,会出现以下编译错误:

main.cpp: In instantiation of ‘class Coverage<unsigned char>’:
<span class="error_line" onclick="ide.gotoLine('main.cpp',27)">main.cpp:27:28</span>:   required from here
main.cpp:12:9: error: no type named ‘type’ in ‘struct std::enable_if’
     int getNb(typename std::enable_if<std::is_signed<T>::value, void>::type) {
         ^~~~~
main.cpp:17:9: error: invalid parameter type ‘std::enable_if::type {aka void}’
     int getNb(typename std::enable_if<std::is_unsigned<T>::value, void>::type) {
         ^~~~~
main.cpp:17:9: error: in declaration ‘int Coverage::getNb(typename std::enable_if::value, void>::type)’
main.cpp: In function ‘int main()’:
main.cpp:28:18: error: ‘class Coverage’ has no member named ‘getNb’
   std::cout << c.getNb() << std::endl;

我知道当我们添加typename std::enable_if为函数参数时,它不会被考虑在内。当我们有同名的成员函数时,它也是唯一使用的方法。


源代码

#include <iostream>
#include <type_traits>

template<typename T>
class Coverage
{
public:
   Coverage(T type) :_type(type) {}

   // signed char 
   int getNb(typename std::enable_if<std::is_signed<T>::value, void>::type) {
      return 1;
   }

   // unsigned int
   int getNb(typename std::enable_if<std::is_unsigned<T>::value, void>::type) {
      return 2;
   }

private:
   T _type;
};

int main()
{
   Coverage<unsigned char> c('c');
   std::cout << c.getNb() << std::endl;
   return 0;
}

标签: c++c++11templatessfinaeclass-template

解决方案


就像@Evg 提到的那样,您还必须对成员函数进行模板化。此外,您需要为它们提供默认值,就像通常的默认值一样nullptr

查看演示

#include <iostream>
#include <type_traits>

template<typename T>
class Coverage {
public:
   Coverage(T type) :_type(type) {}

   //signed char 
   template<typename Type = T> // templated the member!
   int getNb(typename std::enable_if<std::is_signed<Type>::value, void>::type* = nullptr) 
   {
      return 1;
   }

   //unsigned int
   template<typename Type = T> // templated the member!
   int getNb(typename std::enable_if<std::is_unsigned<Type>::value, void>::type* = nullptr)
   {
      return 2;
   }
};

或者为每个函数提供一个尾随返回SFINAE

查看演示

#include <iostream>
#include <type_traits>

template<typename T>
class Coverage {
public:
   Coverage(T type) :_type(type) {}

   template<typename Type = T>
   auto getNb() -> typename std::enable_if<std::is_signed<Type>::value, int>::type
   {
      return 1;
   }


   template<typename Type = T>
   auto getNb() -> typename std::enable_if<std::is_unsigned<Type>::value, int>::type
   {
      return 2;
   }

private:
   T _type;
};

推荐阅读