我有一个将int从storage-ptr中移出的功能:
int&& MoveFromStorage(void const* p)
{
return static_cast<int&&>(*static_cast<int*>(const_cast<void*>(p)));
}
int main()
{
int i = 10;
int&& iRValRef = MoveFromStorage(&i);
}
使用MSVC 2017编译此功能将导致warning C4172: returning address of local variable or temporary
。我没有使用clang或gcc收到此警告。我看不到本地变量或临时地址的返回地址。这是MSVC中的错误吗?
编辑
也许我可以提供更多背景信息:我自己编写了一个std :: variant,并为访问函数编写了以下代码:
template<class AlternativeType>
inline AlternativeType _cast_to(void const* variant_storage)
{
typedef typename std::remove_reference<AlternativeType>::type without_ref;
return static_cast<AlternativeType>(*static_cast<without_ref*>(const_cast<void*>(variant_storage)));
}
template<class AlternativeType, class Visitor>
inline auto _visit_impl(Visitor&& vis, void const* variant_storage)
-> decltype(std::forward<Visitor>(vis)(_cast_to<AlternativeType>(variant_storage)))
{
return std::forward<Visitor>(vis)(_cast_to<AlternativeType>(variant_storage));
}
然后我使用以下功能来填充这些数组:
FPtrType arr[] = { _visit_impl<QualifiedCurrentType>... };
而QualifiedCurrentType,变体的第一种类型是应用了变体的常数和引用性。即如果变体通过r-value-ref传递,则QualifiedCurrentType将是某个其他Type的RvalueRef。在这种情况下,_cast_to会生成警告。
答案 0 :(得分:0)
我无法解释,但是以下更改帮助我修复了代码:
template<class AlternativeType>
inline AlternativeType _cast_to(void const* variant_storage)
{
typedef typename std::remove_reference<AlternativeType>::type without_ref;
without_ref* typedPointer = static_cast<without_ref*>(const_cast<void*>(variant_storage));
return static_cast<AlternativeType>(*typedPointer);
}
因此解决方案是在应用进一步的转换之前存储一些中间的typedPointer。