如何使用std :: is_volatile?

问题描述:

我想禁止对易失性类型的特定操作。要做到这一点,我试图用std::is_volatile,但下面的代码编译没有错误,这不是我想要的。如何使用std :: is_volatile?

为什么is_volatile::valuefalse在下面的情况下?

#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); 
} 
+0

这参数推导是多么模板工程 - 预选赛都没有通过推断值参数类型的一部分。这与本质上相同:'volatile int src = ...; int n = src;'。请注意'n'对src'的限定一无所知。换句话说,左值到右值的转换放弃了限定符。 –

+0

@KerrekSB @KerrekSB可能忽略了一个数组作为参数 –

+0

@ M.M:不,这只是使细节复杂一点,但核心问题依然存在。 –

的问题是,T是不是一个volatile型的。这是volatile char*。等一下,你说,我看到volatile就在那里。没错,但考虑一下:char* volatile是一种易失性类型。 volatile char*不是。这是一个非易失性指针,指向易失性数组。

解决方案:std::is_volatile<typename std::remove_pointer<T>::type>

+4

更好的解决方案:'内联无效DoStuff(T * val)'?接受'T'然后剥掉指针似乎不如接受'T *'明智。 – Yakk

因为函数按值接受它的参数,所以原始参数的cv-qualification丢失。

通过引用接受它:

void DoStuff(T& val) 
+0

考虑到示例参数是一个数组,'T * val'可能会更有意义(但我们缺少上下文) – MSalters

当试图通过值的数组传递,它衰变为一个指向它的第一个元素。

这意味着val实际上是一个int volatile *。因此,它指向一个易变的int,但本身不是易变的。因此,std::is_volatile返回false。

你可以试试服用数组中引用,或使用std::remove_pointer