为啥 void_t 在 SFINAE 中不起作用但 enable_if 起作用
Posted
技术标签:
【中文标题】为啥 void_t 在 SFINAE 中不起作用但 enable_if 起作用【英文标题】:Why void_t doesnt work in SFINAE but enable_if does为什么 void_t 在 SFINAE 中不起作用但 enable_if 起作用 【发布时间】:2021-08-22 09:27:43 【问题描述】:我试图了解 SFINAE
的工作原理,并且正在尝试使用此代码
#include <type_traits>
struct One
using x = int;
;
struct Two
using y = int;
;
template <typename T, std::void_t<typename T::x>* = nullptr>
void func()
template <typename T, std::void_t<typename T::y>* = nullptr>
void func()
/*template <typename T, std::enable_if_t<std::is_same_v<typename T::x, typename T::x>>* = nullptr>
void func()
template <typename T, std::enable_if_t<std::is_same_v<typename T::y, typename T::y>>* = nullptr>
void func() */
int main()
func<One>();
func<Two>();
注释的代码有效,但第一个无效。编译器给了我错误,说有重新定义并且模板参数推导失败。有人可以解释为什么会这样吗?两个void_t
s 应该是独立的吧?因为一行检查x
,另一行检查y
。我该如何解决?
【问题讨论】:
请注意,这适用于make_void
trick。
【参考方案1】:
这似乎与CWG issue #1980 有关(感谢T.C. 纠正我)。
作为一种解决方法,您可以将void_t
定义为:
template<typename... Ts> struct make_void typedef void type;;
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
(from cppreference)
live example on wandbox
【讨论】:
哇这个问题在 gcc 上新安装的 C++17 还没有解决? @VittorioRomeo 他们至少可以在库中使用 make_void 技巧..std::void_t
指定为template <class...> using void_t = void;
这不是 1558。这与声明匹配有关,即两个 func
定义是否实际上声明了不同的函数模板或相同的函数模板。更接近 2037 年。
"所有提示似乎都指向 1558"?不是我。首先,您不会得到“模棱两可的过载”之类的东西,这表明 SFINAE 没有介入;相反,您会得到“重新定义”。其次,如果你删除了两个func
s 之一,那么剩下的一个会被适当地调用——或者产生一个错误。这也与 SFINAE 问题不一致。最后,只要有func
的两个定义,没有任何调用,就足以触发错误。再一次,这与 SFINAE 问题不一致。以上是关于为啥 void_t 在 SFINAE 中不起作用但 enable_if 起作用的主要内容,如果未能解决你的问题,请参考以下文章
为啥jquery plusslider在google chrome中不起作用但在firefox中起作用
为啥“deleteBlocks”在 phpWord 中不起作用?