c++11 enable_if错误-模板参数重新声明
c++11 enable_if error - template parameter re-declaration
我试图得到以下代码编译:
template <class T, typename std::enable_if<!std::is_fundamental<T>::value, int >::type = 0 >
class Calc
{
public:
int operator()( const T& v ) const {
return v.getValue();
}
};
template <class T, typename std::enable_if<std::is_fundamental<T>::value, int >::type = 0 >
class Calc : CalcBase <T>
{
};
在编译时,我得到以下错误:
c.cpp:26: error: template parameter 'typename std::enable_if<(! std::is_fundamental::value), int>::type <anonymous>'
c.cpp:36: error: redeclared here as 'typename std::enable_if<std::is_fundamental::value, int>::type <anonymous>'
此处的目的是,如果传递的模板形参是类,则选择覆盖基类函数调用操作符的Calc版本。如果传递的参数是基本类型,那么我们选择不覆盖基类功能的Calc版本。你能帮我理解一下我怎么才能让它工作吗?
我不认为类模板声明与SFINAE工作:类模板不像函数模板那样重载。你声明了两个同名的主类模板,这是不允许的。
方便的是,SFINAE对于你的用例来说是不必要的:类模板支持部分专门化。您只需使用默认的bool
参数,并将类模板专门化,以确定trait是true
还是false
。例如:template <class T, bool = std::is_fundamental<T>::value>
class Calc
{
public:
int operator()( const T& v ) const {
return v.getValue();
}
};
template <class T>
class Calc<T, false> : CalcBase <T>
{
};
在类模板中使用SFINAE的一种方法是通过局部专门化,使用SFINAE专门化模板参数。
这是一个最小的工作示例,实现了问题中描述的类。
在Calc
的实例化中,模板参数U
要么具有默认类型void
,要么具有类型void
,但通过enable_if
条件为true
,或者如果enable_if
条件为false
,则涉及SFINAE类型错误。
由于U
具有void
的默认参数,类型T
导致所有部分专门化的SFINAE类型错误仍然会导致基于默认参数的类模板的实例化,从而避免编译时错误。注意:在这种特殊情况下,其中一个条件必须是true
,但在其他情况下,使用默认参数会有所帮助。
#include <type_traits>
class NonFundamental {
public:
NonFundamental(int val) : val_(val) {}
int getValue() {
return val_;
}
private:
int val_;
};
template <typename T>
class Calcbase {};
template <typename T, typename U = void>
class Calc {};
template <typename T>
class Calc<T, typename std::enable_if_t<!std::is_fundamental_v<T>>> {
public:
int operator()(const T &v) const {
return v.getValue();
}
};
template <typename T>
class Calc<T, typename std::enable_if_t<std::is_fundamental_v<T>>> : Calcbase<T> {
};
int main() {
Calc<int> calc_obj_1;
Calc<NonFundamental> calc_obj_2;
return 0;
}
相关文章:
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- 新运算符分配的大小大于声明的大小.为什么
- 为什么我不能只用前向声明 c++ 声明类的静态成员?
- 垫子声明:声明尺寸和大小()不同
- 如何从构造函数声明新的私有变量?
- 使用具有新信号槽语法的Qt插件系统在接口类中声明信号
- 使用 basic_string 声明新类型的字符串
- 声明数组时出现 SIGSEGV 错误,而不创建新的 int[size]
- STD :: bad_alloc在声明新的int [n]时
- 了解函数错误的歧义新声明
- 在C++中,如何在没有新元素且不单独声明单个元素的情况下创建"std::initializer_list<base *>"?
- 使用模板在类中声明新函数
- 元编程:动态声明一个新结构
- 使用括号会在声明新节点时会产生错误
- QT应用程序声明新对象后崩溃
- 新声明在使用delete时包含垃圾值和堆损坏
- 为什么新运算符没有声明为 [[nodiscard]]?
- 您只是调用前方声明和原型声明“声明”
- C++:友元声明'声明一个非模板函数
- C++在新函数声明器语法中访问此