C++ 如何使用enable_if进行模板类成员的越界定义

C++ 如何使用enable_if进行模板类成员的越界定义,c++,class,templates,template-specialization,C++,Class,Templates,Template Specialization,我试图理解enable_if的用法,但在这方面我确实没有什么困难。在这里,我编写了一个测试代码,它似乎没有按预期的那样工作 #include <iostream> template <typename T> class Base{ public: template <typename U> U Compute(U a, U b); }; using AddOperation = Base<int>; template<>

我试图理解
enable_if
的用法,但在这方面我确实没有什么困难。在这里,我编写了一个测试代码,它似乎没有按预期的那样工作

#include <iostream>

template <typename T>
class Base{
 public:
  template <typename U>
  U Compute(U a, U b);
};

using AddOperation = Base<int>;

template<>
template<typename U>
typename std::enable_if<!std::is_same<U, bool>::value, U>::type
AddOperation::Compute(U a, U b){
  return a + b;
}

int main(){
  Base<int> b;
  std::cout << b.Compute<int>(10, 2) << std::endl;
  std::cout << b.Compute<bool>(true, false) << std::endl;
  return 0;
}

您也应该在声明中使用
enable_if
,就像定义一样

template <typename T>
class Base{
 public:
  template <typename U>
  typename std::enable_if<!std::is_same<U, bool>::value, U>::type Compute(U a, U b);
};
模板
阶级基础{
公众:
模板
typename std::enable_if::value,U>::类型Compute(U a,U b);
};

事实上,正如我所期望的那样拒绝当前代码,因为声明和定义不匹配

错误:“Compute”的行外定义与“Base”中的任何声明都不匹配


编辑(用于添加问题)

你可以

template <OpType T>
class Base{
 public:
  template <typename U, OpType X = T>
  typename std::enable_if<
             (X == OpType::INT && !std::is_same<U, bool>::value) 
             || 
             (X == OpType::BITWISE && std::is_same<U, bool>::value), U
           >::type
  Compute(U a, U b); 
};

using AddOperation = Base<OpType::INT>;

template<>
template<typename U, OpType X>
typename std::enable_if<
           (X == OpType::INT && !std::is_same<U, bool>::value) 
           || 
           (X == OpType::BITWISE && std::is_same<U, bool>::value), U
         >::type
AddOperation::Compute(U a, U b){ 
  std::cout << a << "," << b << std::endl;
  return a + b;
}

using AndOperation = Base<OpType::BITWISE>;

template<>
template<typename U, OpType X>
typename std::enable_if<
           (X == OpType::INT && !std::is_same<U, bool>::value) 
           || 
           (X == OpType::BITWISE && std::is_same<U, bool>::value), U
         >::type
AndOperation::Compute(U a, U b){
  return a & b;
}
模板
阶级基础{
公众:
模板
typename std::启用\u如果<
(X==OpType::INT&!std::is_same::value)
|| 
(X==OpType::按位&&std::is_same::value),U
>::类型
计算(U a,U b);
};
使用AddOperation=Base;
模板
模板
typename std::启用\u如果<
(X==OpType::INT&!std::is_same::value)
|| 
(X==OpType::按位&&std::is_same::value),U
>::类型
AddOperation::Compute(UA,UB){

std::cout如果目的是仅对
bool
类型禁用它,请为主类模板
Base
实现该方法。您还需要在Compute()声明中启用
If


这并不是你问题的真正答案,但为了可读性,有一种更好的方法禁止
Compute(T,T)
函数的
bool
参数

template <typename T>
class Base{
 public:
  template <typename U>
  U Compute(U a, U b);

  bool Compute(bool , bool) = delete;
};
模板
阶级基础{
公众:
模板
U计算(U a,U b);
bool Compute(bool,bool)=删除;
};

+1,谢谢。虽然我在我的问题中添加了另一个要求。我很想知道你在同一个问题上的输入。谢谢你的输入。理解这个问题。我添加了另一个要求。我很想知道你在同一个问题上的输入。@RachitAgrawal答案已修改。是否可以使用单个函数?因为
Compute
无论如何都是可行的ting过载,声明两个单独的函数似乎是多余的。@RachitAgrawal像这样?(答案已修改。)有趣的是,如果扩展了enum类,那么管理代码就变得非常困难。这是一个不错的解决方案。但是我的要求比我最初发布的要求稍高一些。编辑我的问题以解释我的进一步要求。如果你理解了其他答案,很容易,只需在
std::enable\u if
中添加
&&std::is_same
,这就是boili在基类中定义另一个计算函数。我想知道是否有更好的解决方案。
std::cout << b.Compute<int>(10, 2) << std::endl;       // fine
std::cout << a.Compute<bool>(true, true) << std::endl; // fine
std::cout << b.Compute<bool>(true, true) << std::endl; // error, no matching function
std::cout << a.Compute<int>(10, 2) << std::endl;       // error, no matching function
#include <iostream>

template <typename T>
class Base{
 public:
  template <typename U>
  typename std::enable_if<!std::is_same<U, bool>::value, U>::type Compute(U a, U b);
};

template<typename T>
template<typename U>
typename std::enable_if<!std::is_same<U, bool>::value, U>::type
Base<T>::Compute(U a, U b){
  return a + b;
}

int main(){
  Base<int> b;
  std::cout << b.Compute<int>(10, 2) << std::endl;
  //std::cout << b.Compute<bool>(true, false) << std::endl; --> compile error
  return 0;
}
#include <iostream>

enum class OpType{
  INT,
  BITWISE,
};

template <OpType T>
class Base{
 public:
  template <typename U>
  typename std::enable_if<!std::is_same<U, bool>::value, U>::type Compute(U a, U b);
};

template<OpType T>
template<typename U>
typename std::enable_if<!std::is_same<U, bool>::value, U>::type
Base<T>::Compute(U a, U b){
  return a + b;
}

template <>
struct Base<OpType::BITWISE> {
  template <typename U>
  U Compute(U a, U b) { return a & b;}
};

using AddOperation = Base<OpType::INT>;
using AndOperation = Base<OpType::BITWISE>;

int main(){
  AddOperation b;
  AndOperation a;
  std::cout << b.Compute<int>(10, 2) << std::endl;
  std::cout << a.Compute<bool>(true, true) << std::endl;
  return 0;
}
template <typename T>
class Base{
 public:
  template <typename U>
  U Compute(U a, U b);

  bool Compute(bool , bool) = delete;
};