0

我想使用 SFINAE 来停止显式调用析构函数,因为 MSVS 2010 在对内置类型指针执行时认为它是一个错误。

我该怎么做?

4

3 回答 3

2

您可能会从错误的角度看待它:您不应该排除无效的内容,而应该检测有效的内容。在您的情况下,您正在尝试检查给定类型T是否是类,因此您可以调用析构函数。

也就是说,你想要std::is_class. 如果它不适用于您的编译器,则可以使用Boost.TypeTraits'boost::is_class,它适用于 VC++ 8 和更高版本。

于 2013-09-20T07:43:00.890 回答
1

这显示了如何专门化一个函数,以便在 C++ 中为基本数据类型调用它。

template < class T>
void delete_object(T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = 0) {
    // Do nothing because this is not an object
}

template<class T>
void delete_object(T* object) {
    delete object;
}

int main()
{
    int arithmetic1 = 1;
    delete_object(arithmetic1);
    float arithmetic2 = 1;
    delete_object(arithmetic2);
    Object* object1 = new Object();
    delete_object(object1);

    return 0;
}

这是其他基本测试

std::is_integral<>       - 'char' up to 'long long'
std::is_floating_point   - 'float' up to 'long double'
std::is_signed<>         - signed types
std::is_unsigned<>       - unsigned types
std::is_arithmetic       - is_integral<> OR is_floating_point<>
std::is_fundamental<>    - is_arithmetic<> OR 'void'
于 2013-09-20T04:05:19.667 回答
0
With the following type function we can determine whether a type is a class type:

// traits/isclasst.hpp 

template<typename T> 
class IsClassT { 
  private: 
    typedef char One; 
    typedef struct { char a[2]; } Two; 
    template<typename C> static One test(int C::*); 
    template<typename C> static Two test(…); 
  public: 
    enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 }; 
    enum { No = !Yes }; 
}; 

This template uses SFINAME principle.
The following program uses this type function to test whether certain types and objects are class types:

// traits/isclasst.cpp 

#include <iostream> 
#include "isclasst.hpp" 

class MyClass { 
}; 

struct MyStruct { 
}; 

union MyUnion { 
}; 

void myfunc() 
{ 
} 

enumE{e1}e; 

// check by passing type as template argument 
template <typename T> 
void check() 
{ 
    if (IsClassT<T>::Yes) { 
        std::cout << " IsClassT " << std::endl; 
    } 
    else { 
        std::cout << " !IsClassT " << std::endl; 
    } 
} 

// check by passing type as function call argument 
template <typename T> 
void checkT (T) 
{ 
    check<T>(); 
} 

int main() 
{ 
    std::cout << "int: "; 
    check<int>(); 

    std::cout << "MyClass: "; 
    check<MyClass>(); 

    std::cout << "MyStruct:"; 
    MyStruct s; 
    checkT(s); 

    std::cout << "MyUnion: "; 
    check<MyUnion>(); 

    std::cout << "enum:    "; 
    checkT(e); 

    std::cout << "myfunc():"; 
    checkT(myfunc); 
} 
The program has the following output:

int:      !IsClassT 
MyClass:  IsClassT 
MyStruct: IsClassT 
MyUnion:  IsClassT 
enum:     !IsClassT 
myfunc(): !IsClassT 
于 2013-09-20T07:55:01.350 回答