Как использовать std:: is_volatile?
Я пытаюсь запретить определенную операцию по летучим типам. Для этого я пытаюсь использовать std::is_volatile
, но приведенный ниже код компилируется без ошибок, чего я не хочу.
Почему is_volatile::value
false в приведенном ниже примере?
#include <type_traits>
template<typename T>
inline void DoStuff(T val) {
static_assert(!std::is_volatile<T>::value, "No volatile types plz");
//...
}
int main() {
volatile char sometext[261];
DoStuff(sometext);
}
Ответы
Ответ 1
Проблема заключается в том, что T не является типом volatile
вообще. Это volatile char*
. Подождите, вы говорите, я вижу volatile
прямо там. Правда, но учтите следующее: char* volatile
является изменчивым типом. volatile char*
нет. Он является энергонезависимым указателем на энергозависимый массив char
.
Решение: std::is_volatile<typename std::remove_pointer<T>::type>
Ответ 2
При попытке передать массив по значению он распадается на указатель на его первый элемент.
Это означает, что val
на самом деле a int volatile *
. Таким образом, он указывает на volatile int
, но сам по себе не является изменчивым. Следовательно, std::is_volatile
возвращает false.
Вы можете попробовать взять массив по ссылке или использовать std::remove_pointer
.
Ответ 3
Поскольку функции принимают свой аргумент по значению, cv-квалификация исходного аргумента теряется.
Примите его по ссылке:
void DoStuff(T& val)