C++ 如果with is_枚举不起作用,则启用_
MCVE: 为什么这不起作用?我该如何修复它C++ 如果with is_枚举不起作用,则启用_,c++,c++11,sfinae,C++,C++11,Sfinae,MCVE: 为什么这不起作用?我该如何修复它 背景:这是一个尝试性的解决方案您看到的错误与自动类型推断有关,而不是如果和是枚举则启用 下面的工作 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: candidat
背景:这是一个尝试性的解决方案您看到的错误与自动类型推断有关,而不是
如果
和是枚举
则启用
下面的工作
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);
^
然后
现在T
用于推导上下文。SFINAE仍会出现,但不会阻止模板类型推断
或者您可以等待C++1z概念,它可以自动执行上述构造(基本上)
看看这个链接的问题,解决问题的简单方法是标记分派
template<class T,class=typename std::enable_if< std::is_enum<T>::value >::type>
bool func( T &t, int x ) {
}
模板
布尔函数(T&T,int x)
{
//做些事情。。。
}
不过,我希望有三个不同的职能机构:
我们有3个案例:
- 不是一个枚举
- T是无符号字符
- 其他一切
template<typename T>
bool func(T &t, int x)
{
// do stuff...
}
名称空间详细信息{
模板
布尔函数(T&T,int x,std::true\u type/*是\u enum*/,std::false\u type){
}
模板
布尔函数(T&T,int x,std::false\u type,std::true\u type/*无符号字符*/){
}
模板
布尔函数(T&T,int x,std::false\u类型,std::false\u类型){
//都不是
}
}
模板
布尔函数(T&T,int x){
返回详细信息::func(t,x,std::is_enum{},std::is_same{});
}
现在使用常规重载规则在3个函数之间进行选择。如果您的类型同时是
enum
和unsigned char
(不可能),则会出现编译时错误。您正在非推断上下文中使用模板参数T
从§14.8.2.5/5[临时扣减类型]
非推断上下文为:-使用限定id指定的类型的嵌套名称说明符。
- 要解决此问题,请将
启用\u if
移动到虚拟模板参数
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>{} );
}
template<typename T,
typename = typename std::enable_if< std::is_enum<T>::value, T >::type>
bool func( T &t, int x )
{
// ...
}
或者在返回类型中使用enable\u if
表达式
template<typename T,
typename std::enable_if< std::is_enum<T>::value, int >::type* = nullptr>
bool func( T &t, int x )
{
// ...
}
模板
typename std::enable_如果::type
函数(T&T,int x)
{
// ...
}
好的,这很重要。它似乎也适用于包装器:template bool func2(T&T,int x){return func(T,x);}
Right,我在尝试您的第一个建议时确实遇到了多个定义错误,无法理解它们出现的原因,因此也感谢您的解释:)
template<class T>
bool func( typename blah<T>::type );
template<class T,class=typename std::enable_if< std::is_enum<T>::value >::type>
bool func( T &t, int x ) {
}
template<typename T>
bool func(T &t, int x)
{
// do stuff...
}
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>{} );
}
template<typename T,
typename = typename std::enable_if< std::is_enum<T>::value, T >::type>
bool func( T &t, int x )
{
// ...
}
template<typename T,
typename std::enable_if< std::is_enum<T>::value, int >::type* = nullptr>
bool func( T &t, int x )
{
// ...
}
template<typename T>
typename std::enable_if< std::is_enum<T>::value, bool >::type
func( T &t, int x )
{
// ...
}