如何检测模板参数是否为内置函数?

时间:2013-09-20 02:27:35

标签: c++ visual-studio

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

我该怎么做?

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分: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'

答案 2 :(得分: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