如何禁用指针作为模板类型名

Vec*_*zer 7 c++ templates class

当使用指针作为模板类型名称时,我想使其无法实例化以下类:

template <typename T>
class MyClass{
//...
T payload;
//...
};
Run Code Online (Sandbox Code Playgroud)

所以 MyClass<int>是好的,但 MyClass<int*>不是。

如果我可以禁止带有struct指针的类的实例化,那就太好了。

Nat*_*ica 7

您可以通过几种方法来执行此操作。您可以使用SFINAE将模板限制为非指针类型,例如

template <typename T, std::enable_if_t<!std::is_pointer_v<T>, bool> = true>
class MyClass{
    //...
    T payload;
    //...
};
Run Code Online (Sandbox Code Playgroud)

但是,这可能会使您很难理解编译器错误。使用,static_assert您可以添加自己的自定义错误消息,例如

template <typename T>
class MyClass {
    //...
    static_assert(!std::is_pointer_v<T>, "MyClass<T> requires T to be a non pointer type");
    T payload;
    // ...
};
Run Code Online (Sandbox Code Playgroud)


Vit*_*meo 5

您可以使用static_assert+ std::is_pointer_v

template <typename T>
class MyClass {
    static_assert(!std::is_pointer_v<T>);
    // ...
};
Run Code Online (Sandbox Code Playgroud)


Ayx*_*xan 5

如果您没有使用C ++ 11 std::is_pointerstatic_assert,则可以定义一个特殊化,并将其保留为未定义:

template <typename T>
class MyClass {

};

template<class T>
class MyClass<T*>; // Requires non-pointer types

template<class T>
class MyClass<T* const>; // Requires non-pointer types

template<class T>
class MyClass<T* const volatile>; // Requires non-pointer types

template<class T>
class MyClass<T* volatile>; // Requires non-pointer types

int main() {
    MyClass<int> mc1;  // Works fine
    MyClass<int*> mc2; // Error
}
Run Code Online (Sandbox Code Playgroud)