Как отключить указатели в качестве шаблонных названий - PullRequest
6 голосов
/ 04 ноября 2019

Я хотел бы сделать невозможным создание экземпляра следующего класса, когда указатель используется в качестве имени типа шаблона:

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

Так что MyClass<int> в порядке, но MyClass<int*> - нет.

Было бы замечательно, если бы я мог запретить создание экземпляров класса с struct, на котором есть указатель.

Ответы [ 4 ]

7 голосов
/ 04 ноября 2019

Есть несколько способов сделать это. Вы можете использовать SFINAE , чтобы ограничить шаблон типами без указателей, такими как

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

Но это может привести к довольно сложным для понимания ошибкам компилятора. Используя 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;
    // ...
};
5 голосов
/ 04 ноября 2019

Если у вас нет C ++ 11 для использования std::is_pointer и static_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
}
5 голосов
/ 04 ноября 2019

Вы можете использовать static_assert + std::is_pointer_v:

template <typename T>
class MyClass {
    static_assert(!std::is_pointer_v<T>);
    // ...
};
2 голосов
/ 04 ноября 2019

Было бы замечательно, если бы я мог запретить создание экземпляров класса со структурой, в которой есть указатель.

Это невозможно в C ++.

Обратите внимание, что умные указатели имеют структуру , в которой есть указатели;std :: is_pointer не распознает их, поэтому, если вы хотите запретить их, вам нужно предоставить отдельную мета-функцию (не очень сложную).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...