template<typename T>
struct S {
using type = T;
};
volatile S<int> s;
template<typename T>
void f(T& v) {
using n = typename T::type;
S<n>::_; // to show
}
int main() {
f(s);
}
在f
,T
被推断为volatile S<int>
,但n
只是int
。我需要做些什么来保护volatile
,也就是让n
成为volatile int
?
using n = typename std::conditional< std::is_volatile<T>::value,
volatile typename T::type,
typename T::type >::type;
如果volatile
是n
,则将T
添加到volatile
。
对于funsies。如果您经常需要执行此类操作,则可以将其封装在元函数中。这是c++17中可能的实现:
#include <type_traits>
template<class Trait, typename=void>
struct propogate_cv_to_type{};
template<class Trait>
struct propogate_cv_to_type<Trait, std::void_t<typename Trait::type>>
{ using type = typename Trait::type; };
template<class Trait>
struct propogate_cv_to_type<Trait const, std::void_t<typename Trait::type>>
{ using type = typename Trait::type const; };
template<class Trait>
struct propogate_cv_to_type<Trait volatile, std::void_t<typename Trait::type>>
{ using type = typename Trait::type volatile; };
template<class Trait>
struct propogate_cv_to_type<Trait const volatile, std::void_t<typename Trait::type>>
{ using type = typename Trait::type const volatile; };
这是SFINAE友好的,所以如果传递的类型没有::type
成员,它也不会。否则,它通过将限定符转发到它上来公开相同的类型。
Here it适用于您的示例。