Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable pointers as template typenames

I would like to make it impossible to instantiate the following class when a pointer is used as the template typename:

template <typename T>
class MyClass{
//...
T payload;
//...
};

So MyClass<int> is fine but MyClass<int*> is not.

It would be wonderful if I can prohibit the instantiation of the class with a struct that has a pointer in it.

like image 293
Vectorizer Avatar asked Nov 04 '19 15:11

Vectorizer


Video Answer


3 Answers

There are a couple ways you can do this. You can use SFINAE to constrain the template to non-pointer types like

template <typename T, std::enable_if_t<!std::is_pointer_v<T>, bool> = true>
class MyClass{
    //...
    T payload;
    //...
};

But this can give some pretty hard to understand compiler errors. Using a static_assert you can add your own custom error message like

template <typename T>
class MyClass {
    //...
    static_assert(!std::is_pointer_v<T>, "MyClass<T> requires T to be a non pointer type");
    T payload;
    // ...
};
like image 169
NathanOliver Avatar answered Sep 26 '22 16:09

NathanOliver


You can use static_assert + std::is_pointer_v:

template <typename T>
class MyClass {
    static_assert(!std::is_pointer_v<T>);
    // ...
};
like image 44
Vittorio Romeo Avatar answered Sep 22 '22 16:09

Vittorio Romeo


If you don't have C++11 to use std::is_pointer and static_assert, you can define a specialization and leave it undefined:

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
}
like image 43
Ayxan Haqverdili Avatar answered Sep 23 '22 16:09

Ayxan Haqverdili