我正在为嵌入式设备开发应用程序,因此没有type_traitsenable_if(编译器质量差)。我自己创建了它们:

template <typename T>
struct is_pointer_t{
    enum{value = false};
};

template <typename T>
struct is_pointer_t<T*>{
    enum{value = true};
};


constsvolatiles的类似声明。

现在执行enable_if

template <bool boolean, typename T = void>
struct enable_if{};

template <typename T>
struct enable_if<true, T>{
    typedef T type;
};


现在,我想拥有一个类,该类基于我使用的指针或普通类型,它们是否在其上调用析构函数,因此,如果我可以使用模板化析构函数,那将是很好的。但是我不知道如何做,因为我才刚刚开始理解模板编程。以下尝试失败:

template <typename T>
class pointerOrNot{
public:

    template <typename U>
    void one();
};

template <typename T>
template <typename enable_if<is_pointer_t<T>::value>::type>
void pointerOrNot<T>::one(){
    std::cout << "Success1" << std::endl;
}

template <typename T>
template <typename enable_if<!is_pointer_t<T>::value>::type>
void pointerOrNot<T>::one(){
    std::cout << "Success2" << std::endl;
}


它说它与定义不匹配。因此,我尝试了以下操作:

template <typename T>
class pointerOrNot{
public:

    template <typename enable_if<is_pointer_t<T>::value>::type>
    void one();
    template <typename enable_if<!is_pointer_t<T>::value>::type>
    void one();
};


但是然后one()之一将空类型作为模板,并且编译失败。我怎样才能做到这一点?也可以用析构函数做到这一点吗?

最佳答案

首先让我们考虑以下类的指针:

template <typename T>
struct Introducer{

  void intro(){
    std::cout<<"I'm a pointer, I point to adress "<<mem<<std::endl;
  }

  T mem;
  Introducer(T m):mem(m){}
};


它适用于指针,但也适用于非指针:

  Introducer<int> i(10);
  i.intro();//just fine!


我们希望在编译期间检测到这种滥用,并且还将Introducer更改为

template <typename T>
struct Introducer{

  typename enable_if<is_pointer_t<T>::value, void>::type //this is the return type of the function
  intro(){
    std::cout<<"I'm a pointer, I point to adress "<<mem<<std::endl;
  }

  ...
};


现在,编译器不允许我们在Introducer中使用非指针。下一步,我们希望通过SFINAE为非指针提供特殊功能:

template <typename T>
struct Introducer{
  typename enable_if<is_pointer_t<T>::value, void>::type
  intro(){
    std::cout<<"I'm a pointer, I point to adress "<<mem<<std::endl;
  }

  typename enable_if<!is_pointer_t<T>::value, void>::type
  intro(){
    std::cout<<"I'm a non-pointer, my value is "<<mem<<std::endl;
  }

  ...
};


地狱,它甚至不编译!让我们更仔细地阅读有关SFINAE的文章:


  如果替换导致无效的类型或表达式,请键入
  推论失败。无效的类型或表达式将是
  如果使用替换参数编写,则格式错误。仅无效
  函数类型的直接上下文中的类型和表达式
  其模板参数类型可能会导致推导失败。


T不在即时上下文中,因此SFINAE不起作用,让我们将T引入即时上下文中:

template <typename T>
struct Introducer{

  template <typename C=T>
  typename enable_if<is_pointer_t<C>::value, void>::type
  intro(){
    std::cout<<"I'm a pointer, I point to adress "<<mem<<std::endl;
  }


  template <typename C=T>
  typename enable_if<!is_pointer_t<C>::value, void>::type
  intro(){
    std::cout<<"I'm a non-pointer, my value is "<<mem<<std::endl;
  }

  ...
};


现在的程序

int main(){
  Introducer<float*> fp(NULL);
  fp.intro();

  //But this works also:
  Introducer<int> i(10);
  i.intro();
}


结果是:

I'm a pointer, I point to adress 0
I'm a non-pointer, my value is 10


那析构函数呢?最简单的方法是从析构函数调用SFINAE-destruction-function(我从未见过SFINAE析构函数,并且不知道如何编写一个,但这并不意味着什么):

template <typename T>
struct Introducer{
  ...

    ~Introducer(){
    intro();
    std::cout<<"and I'm deleted..."<<std::endl;
  }
};

关于c++ - 类中的C++ enable_if-不同的销毁方式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34705800/

10-13 06:18