我可以用 decltype 替换 enable_if 吗
Can I Just Replace enable_if With decltype
在 understanding decltype
with 2 arguments 之后 我想知道,我可以用它代替 enable_if
吗?例如:
template <typename T>
decltype(T(), declval<bool>()) isConstructable() { return true; }
2015 年 Visual Studio isConstructable<int>
成功,isConstructable<istream>
失败:http://rextester.com/YQI94257 But on gcc I have to do:
template <typename T>
enable_if_t<decltype(T(), true_type())::value, bool> isConstructable() { return true; }
decltype
版本应该有效,还是我只是在利用非标准的 Microsoftianisim?
std::declval<bool>()
的类型是bool&&
,不是bool
。这就是警告的来源 - true
需要通过引用返回。
像这样的东西应该在没有警告的情况下编译:
bool ok() { return true; }
template <typename T>
decltype(T(), ok()) is_constructable() { return true; }
int main() {
cout << is_constructable<int>() << endl;
}
如 所述,如果您这样做:
is_rvalue_reference_v<decltype(isConstructable<int>())>
On gcc you'll get true
and on Visual Studio you'll get false
. So the reason this fails on gcc is that it's always undefined behavior to return an r-value reference to an object which is about to be destroyed:
declval
return 应该 r-value 引用吗?
declval
的return类型实际上是:
T&&
unless T
is (possibly cv-qualified) void
, in which case the return type is T
因此这是一个“Microsoftianisim”。可以通过删除 declval
:
来完成与平台无关的代码
template <typename T>
decltype(T(), bool()) isConstructable() { return true; }
gcc Example Visual Studio Example
T
可能使 ,
运算符超载,在这种情况下需要缓冲 void()
:
template <typename T>
decltype(T(), void(), bool()) isConstructable() { return true; }
在 understanding decltype
with 2 arguments 之后 我想知道,我可以用它代替 enable_if
吗?例如:
template <typename T>
decltype(T(), declval<bool>()) isConstructable() { return true; }
2015 年 Visual Studio isConstructable<int>
成功,isConstructable<istream>
失败:http://rextester.com/YQI94257 But on gcc I have to do:
template <typename T>
enable_if_t<decltype(T(), true_type())::value, bool> isConstructable() { return true; }
decltype
版本应该有效,还是我只是在利用非标准的 Microsoftianisim?
std::declval<bool>()
的类型是bool&&
,不是bool
。这就是警告的来源 - true
需要通过引用返回。
像这样的东西应该在没有警告的情况下编译:
bool ok() { return true; }
template <typename T>
decltype(T(), ok()) is_constructable() { return true; }
int main() {
cout << is_constructable<int>() << endl;
}
如
is_rvalue_reference_v<decltype(isConstructable<int>())>
On gcc you'll get true
and on Visual Studio you'll get false
. So the reason this fails on gcc is that it's always undefined behavior to return an r-value reference to an object which is about to be destroyed:
declval
return 应该 r-value 引用吗?
declval
的return类型实际上是:
T&&
unlessT
is (possibly cv-qualified)void
, in which case the return type isT
因此这是一个“Microsoftianisim”。可以通过删除 declval
:
template <typename T>
decltype(T(), bool()) isConstructable() { return true; }
gcc Example Visual Studio Example
T
可能使 ,
运算符超载,在这种情况下需要缓冲 void()
:
template <typename T>
decltype(T(), void(), bool()) isConstructable() { return true; }