enable_if似乎在一个类外面工作,但不在内部 [英] enable_if seems to work outside a class but not inside

查看:107
本文介绍了enable_if似乎在一个类外面工作,但不在内部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是我有点奇怪的代码:

Here is my somewhat odd code:

template <typename T&>
class A {  
public:  
  void b(typename std::enable_if<!std::is_pointer<T>::value, T>;::type o) {}  
  void b(typename std::enable_if<std::is_pointer<T>::value, T>;::type o) {}  
};  

template <typename T>  
void b(typename std::enable_if<!std::is_pointer<T>::value, T>::type o) {}  
template <typename T>  
void b(typename std::enable_if<std::is_pointer<T>::value, T>::type o) {}  

如果I ifdef ,则输出方法 b ,然后调用 b )其中 pi int * ,一切都编译。

If I ifdef out the method b and call b<int *>(pi) where pi is int *, everything compiles.

如果我 ifdef 出函数 b (外部类)并调用 A ,我得到以下错误:

If I ifdef out the function b (outside class) and call A<int *> a; a.b(pi), I get the following error:

命名为'type'in'std :: __ 1 :: enable_if< false,int *>'

为什么不一致,如何解决这个问题,以便我可以使用A中的方法?

Why the inconsistency and how can I fix the problem so that I can use the methods in A?

推荐答案

问题是,SFINAE只在重载解析时才起作用,只有函数模板。在您的方法案例中,整个是一个模板,这意味着没有模板参数的替换(请记住:SFINAE ==

The problem is, that SFINAE only works during overload resolution and only if the function itself is a template. In your method case, the whole class is a template, meaning that there is no substitution of the template parameter (remember: SFINAE == "Substitution Failure Is Not An Error").

在实例化时,方法签名看起来像这样(永远不会调用它们):

At the point of instantiation, the method signatures look like this (nevermind the call to them):

void A<int*>::b(std::enable_if<false, int*>::type o) // error
void A<int*>::b(std::enable_if<true, int*>::type o)

为了解决这个问题,还要创建方法模板:

To fix this, make the methods templates too:

template<class T>
class A{
public:
  template<class U>
  void b(U o, typename std::enable_if<!std::is_pointer<U>::value>::type* = 0){}
  // same for the other version
};

另一方面,让模板参数被推导是更好的方式使用SFINAE,应该修改自由函数,使其看起来像这样:

On a side note, letting the template argument get deduced is the better way to use SFINAE, so you should modify the free functions to look like this:

template<class T>
void b(T o, typename std::enable_if<!std::is_pointer<T>::value>::type* = 0){}
// same for the other version

在C ++ 11中,您甚至可以使用SFINAE的模板参数:

In C++11, you can even use the template parameters for SFINAE:

template<class T, EnableIf<std::is_pointer<T>> = {}>
void b(T o);

使用从这里

namespace detail{ enum class enabler{}; }

template<class Cond, class T = detail::enabler>
using EnableIf = typename std::enable_if<C::value, T>::type;

这篇关于enable_if似乎在一个类外面工作,但不在内部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆