我有如下代码,它通过转发引用接受 std::aligned_storage_t
参数,并且应该将其reinterpret_cast
转换为另一种类型并将其返回给用户。
template <typename AlignedStorageType, typename TypeToReturnAs>
decltype(auto) forward_as_another_type(AlignedStorageType&& storage) {
return *reinterpret_cast<TypeToReturnAs*>(&storage);
}
storage
在返回类型中的引用类型有没有好的维护方式?例如,如果存储是一个右值引用,那么我希望返回类型也是一个右值引用。
最佳答案
首先,翻转模板参数。您希望推导 AlignedStorageType
并显式指定另一个:
template <typename TypeToReturnAs, typename AlignedStorageType>
decltype(auto) forward_as_another_type(AlignedStorageType&& storage) {
return *reinterpret_cast<TypeToReturnAs*>(&storage);
}
接下来,您基本上想要的是有条件地转换表达式。如果 AlignedStorageType&&
是一个 X&&
,您希望将其转换为 TypeToReturnAs&&
。如果是 X&
,则为 TypeToReturnAs&
。如果 X const&
,作为 TypeToReturnAs const&
。
我们可以添加一个类型特征来匹配引用:
template <class T, class U> struct match_reference;
template <class T, class U> struct match_reference<T&, U> { using type = U&; };
template <class T, class U> struct match_reference<T const&, U> { using type = U const&; };
template <class T, class U> struct match_reference<T&&, U> { using type = U&&; };
template <class T, class U> using match_reference_t = typename match_reference<T,U>::type;
然后:
template <typename TypeToReturnAs, typename AlignedStorageType>
decltype(auto) forward_as_another_type(AlignedStorageType&& storage) {
using R = match_reference_t<AlignedStorageType&&, TypeToReturnAs>;
return static_cast<R>(*reinterpret_cast<TypeToReturnAs*>(&storage));
}
或者,如果您只是一次性使用它,您可以将该逻辑编写为条件:
template <typename TypeToReturnAs, typename AlignedStorageType>
decltype(auto) forward_as_another_type(AlignedStorageType&& storage) {
using R = std::conditional_t<
std::is_lvalue_reference<AlignedStorageType>::value,
TypeToReturnAs&,
TypeToReturnAs&&>;
return static_cast<R>(*reinterpret_cast<TypeToReturnAs*>(&storage));
}
或:
using R = std::conditional_t<
std::is_lvalue_reference<AlignedStorageType>::value,
TypeToReturnAs&,
TypeToReturnAs>;
return std::forward<R>(*reinterpret_cast<TypeToReturnAs*>(&storage));
关于c++ - 将对类的引用转发为另一种类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43191809/