C++ 将对类的引用转发为其他类型

C++ 将对类的引用转发为其他类型,c++,c++11,c++14,reinterpret-cast,perfect-forwarding,C++,C++11,C++14,Reinterpret Cast,Perfect Forwarding,我有如下代码,它通过转发引用接受std::aligned_storage_t参数,并且应该将该参数重新解释为另一种类型,并将其返回给用户 template <typename AlignedStorageType, typename TypeToReturnAs> decltype(auto) forward_as_another_type(AlignedStorageType&& storage) { return *reinterpret_cast<

我有如下代码,它通过转发引用接受
std::aligned_storage_t
参数,并且应该
将该参数重新解释为另一种类型,并将其返回给用户

template <typename AlignedStorageType, typename TypeToReturnAs>
decltype(auto) forward_as_another_type(AlignedStorageType&& storage) {
    return *reinterpret_cast<TypeToReturnAs*>(&storage);
}
模板
decltype(自动)作为另一种类型转发(AlignedStorageType&&storage){
返回*重新解释和存储;
}

是否有一种好方法来维护返回类型中的
存储
引用类型?例如,如果存储是右值引用,那么我希望返回类型也是右值引用。

首先,翻转模板参数。您希望推导
AlignedStorageType
,并明确指定另一个:

template <typename TypeToReturnAs, typename AlignedStorageType>
decltype(auto) forward_as_another_type(AlignedStorageType&& storage) {
    return *reinterpret_cast<TypeToReturnAs*>(&storage);
}
然后:

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));
}
模板
decltype(自动)作为另一种类型转发(AlignedStorageType&&storage){
使用R=匹配参考;
返回静态转换(*重新解释转换和存储));
}
或者,如果您仅将此作为一次性使用,则可以将该逻辑作为条件写入:

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));
}
模板
decltype(自动)作为另一种类型转发(AlignedStorageType&&storage){
使用R=std::conditional\u t<
std::is_lvalue_reference::value,
键入ToReturnas&,
键入ToReturnas&&>;
返回静态转换(*重新解释转换和存储));
}
或:

使用R=std::conditional\u t<
std::is_lvalue_reference::value,
键入ToReturnas&,
键入返回>;
返回标准::转发(*重新解释和存储));

谢谢!这太棒了!我打算在我的代码中推导出
AlignedStorageType
。我只是想知道除了制作自定义特征之外,是否还有其他方法可以做到这一点。你能解释一下为什么在上一个示例中,
std::conditional\u t
的第三个参数是
TypeToReturnAs
而不是
TypeToReturnAs&
?@奇怪的是,这两种方法都是一样的,因为
forward
会返回一个
T&
。它只是稍微短一点,更适合
forward
的常用用法(比如,通常不编写
std::forward(x)
),但是
std::forward
有两个重载,一个接受右值,另一个接受左值(一个接受左值引用,另一个接受右值引用),那么,最后一个示例不总是与左值引用匹配吗?因为从
重新解释_cast
中取消引用的值不是右值(xvalue或prvalue)。还是我错了?@奇怪的是,它总是与左值引用匹配。与编写
std::forward(x)
时的方式相同,无论是否移动,您都在调用左值引用重载,因为
x
始终是一个左值。返回值
typename是否会像std::move help中那样删除\u reference::type&
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));