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;
};