关于enable_if和模板专门化的适当使用,我遇到了一个问题。
修改示例后(出于保密原因),下面是一个可比的示例:
我有一个名为“less”的函数,它检查第一个arg是否小于第二个arg。假设我想根据输入的类型有两种不同的实现——1种实现用于integer,另一种实现用于double。
我目前掌握的密码是这样的
#include <type_traits>
#include <iostream>
template <class T,
class = typename std::enable_if<std::is_floating_point<T>::value>::type>
bool less(T a, T b) {
// ....
}
template <class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>
bool less(T a, T b) {
// ....
}
int main() {
float a;
float b;
less(a,b);
return 0;
}
上面的代码不编译,因为——它说我正在重新定义更少的方法。
错误是:
Z.cpp:15:19: error: template parameter redefines default argument
class = typename std::enable_if<std::is_integral<T>::value>::type>
^
Z.cpp:9:19: note: previous default template argument defined here
class = typename std::enable_if<std::is_floating_point<T>::value>::type>
^
Z.cpp:16:11: error: redefinition of 'less'
bool less(T a, T b) {
^
Z.cpp:10:11: note: previous definition is here
bool less(T a, T b) {
^
Z.cpp:23:5: error: no matching function for call to 'less'
less(a,b);
^~~~
Z.cpp:15:43: note: candidate template ignored: disabled by 'enable_if'
[with T = float]
class = typename std::enable_if<std::is_integral<T>::value>::type>
^
3 errors generated.
有人能指出这里的错误吗?
默认模板参数不是函数模板签名的一部分。因此,在您的示例中,有两个相同的重载less
,这是非法的。clang抱怨重新定义默认参数(根据§14.1/12[temp.param]的规定,这也是非法的),而gcc产生以下错误消息:
错误:重新定义模板
要修复错误,请将
enable_if
表达式从默认参数移动到伪模板参数
template <class T,
typename std::enable_if<std::is_floating_point<T>::value, int>::type* = nullptr>
bool less(T a, T b) {
// ....
}
template <class T,
typename std::enable_if<std::is_integral<T>::value, int>::type* = nullptr>
bool less(T a, T b) {
// ....
}
另一个选项是在返回类型中使用
enable_if
,尽管我觉得这更难理解。
template <class T>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type
less(T a, T b) {
// ....
}
template <class T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
less(T a, T b) {
// ....
}
还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案
ii)当我更改代码并删除void_t时 0和0打印。表示,专门化是,所以我们使用基本模板。对于字符串,专门化无论如何都失败了。 我的问题:iii)有趣的部分。如果现在我把第一行改为使用int作为默认类型 有人能给我解释一下在iii)发生了什么吗?
考虑代码: Microsoft Visual Studio 2013给出以下错误: C2912:显式特化'CByteArray序列化(const HLVariant 错误C2783:“CByteArray serialize(const std::enable_if::type 错误表明没有
在本文中,他们说(c)是(b)的显式专门化。我的疑问是,为什么我们不能说它是(a)的显式专门化?因为我们可以为任何特定类型专门化模板。所以,当专门化int*时,为什么他们说(c)显式专门化(b)。 任何评论都将有助于理解事情。
我有一个通用算法,需要访问其模板类型的特征。有一个特征类可以专门用于提供这些特征。 在我的类中使用此算法时,我想将其与类中定义的私有类型一起使用。 然而,专门化只能发生在或全局范围内,而我的类是不可访问的。 是否有可能以某种方式专门化具有私有类型的模板,至少在可访问此类型的范围内? 也许可以将这个专门化声明为一个类?
这里有一个最小的例子来说明我遇到的问题。 模板成员显式专用于基类中的。模板的代码是显式生成的,并在成员中调用。 我发现的第一个问题是: 该错误是由于在main中调用造成的。可以通过调用来避免这种情况。为什么在的实例中显然是不可见的?