如何使用std :: is_volatile?
我想禁止对易失性类型的特定操作。要做到这一点,我试图用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);
}
的问题是,T是不是一个volatile
型的。这是volatile char*
。等一下,你说,我看到volatile
就在那里。没错,但考虑一下:char* volatile
是一种易失性类型。 volatile char*
不是。这是一个非易失性指针,指向易失性数组。
解决方案:std::is_volatile<typename std::remove_pointer<T>::type>
更好的解决方案:'内联无效DoStuff(T * val)'?接受'T'然后剥掉指针似乎不如接受'T *'明智。 – Yakk
因为函数按值接受它的参数,所以原始参数的cv-qualification丢失。
通过引用接受它:
void DoStuff(T& val)
考虑到示例参数是一个数组,'T * val'可能会更有意义(但我们缺少上下文) – MSalters
当试图通过值的数组传递,它衰变为一个指向它的第一个元素。
这意味着val
实际上是一个int volatile *
。因此,它指向一个易变的int
,但本身不是易变的。因此,std::is_volatile
返回false。
你可以试试服用数组中引用,或使用std::remove_pointer
。
这参数推导是多么模板工程 - 预选赛都没有通过推断值参数类型的一部分。这与本质上相同:'volatile int src = ...; int n = src;'。请注意'n'对src'的限定一无所知。换句话说,左值到右值的转换放弃了限定符。 –
@KerrekSB @KerrekSB可能忽略了一个数组作为参数 –
@ M.M:不,这只是使细节复杂一点,但核心问题依然存在。 –