gpt4 book ai didi

c++ - 带有 is_enum 的 enable_if 不起作用

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:58:09 26 4
gpt4 key购买 nike

MCVE:

#include <type_traits>

template<typename T>
bool func( typename std::enable_if< std::is_enum<T>::value, T >::type &t, int x )
{
}

enum class Bar { a,b,c };

int main()
{
Bar bar{Bar::a};
func(bar, 1);
}

我希望 func(bar, 1); 符合我对 func 的定义,但是 g++ 报告:

sfi.cc: In function 'int main()':
sfi.cc:13:17: error: no matching function for call to 'func(Bar&, int)'
func(bar, 1);
^
sfi.cc:13:17: note: candidate is:
sfi.cc:4:10: note: template<class T> bool func(typename std::enable_if<std::is_e
num<_Tp>::value, T>::type&, int)
bool func( typename std::enable_if< std::is_enum<T>::value, T >::type &t, int x )
^
sfi.cc:4:10: note: template argument deduction/substitution failed:
sfi.cc:13:17: note: couldn't deduce template parameter 'T'
func(bar, 1);
^

为什么这行不通,我该如何解决?

背景:这是对 this problem 的尝试性解决方案。

最佳答案

template<typename T>
bool func( typename std::enable_if< std::is_enum<T>::value, T >::type &t, int x )

T 在上面的非推导上下文中使用。这意味着它不会扣除 T ,因为它(在一般情况下)需要反转任意图灵完备转换,这是不可能的。

func 的第一个参数是 enum class Bar,第二个参数是 int。从这里你期望它推断出 T

虽然将 T 设置为 enum class Bar 确实可以解决问题,但 C++ 不会猜测。它模式匹配。

假设我们有:

template<class T>
struct blah { using type=int; };
template<>
struct blah<int> { using type=double; };

然后

template<class T>
bool func( typename blah<T>::type );

如果有人将 int 传递给 func ,应该为 T 推导什么类型?这是一个玩具示例:foo<T>::type 可以执行图灵完备算法将 T 映射到相关类型。在一般情况下,不可能将其反转甚至确定反转是否不明确。所以 C++ 甚至不会尝试,即使是在简单的情况下,因为简单和复杂之间的界限很快变得模糊。

解决您的问题:

template<class T,class=typename std::enable_if< std::is_enum<T>::value >::type>
bool func( T &t, int x ) {
}

现在 T 用于推导上下文。 SFINAE 仍然会发生,但不会阻止模板类型推导。

或者您可以等待 C++1z 概念,它自动执行上述构造(基本上)。


查看链接的问题,解决问题的简单方法是使用标签调度。

template<typename T> 
bool func(T &t, int x)
{
// do stuff...
}

但是我想要三个不同的函数体:

我们有 3 个案例:

  • T 是一个枚举

  • T 为无符号字符

  • 一切

所以,调度:

namespace details {
template<class T>
bool func( T& t, int x, std::true_type /* is_enum */, std::false_type ) {
}
template<class T>
bool func( T& t, int x, std::false_type, std::true_type /* unsigned char */ ) {
}
template<class T>
bool func( T& t, int x, std::false_type, std::false_type ) {
// neither
}
}
template<class T>
bool func( T& t, int x ) {
return details::func( t, x, std::is_enum<T>{}, std::is_same<unsigned char, T>{} );
}

现在正常的重载规则用于在 3 个函数之间进行选择。如果您以某种方式拥有同时为 enumunsigned char(不可能)的类型,则会出现编译时错误。

关于c++ - 带有 is_enum 的 enable_if 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29762813/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com