想象一下某个函数(RetrieveResult),通过指针/引用/值返回一个对象--我不知道也不想知道,因为事情可能会变。我只想使用auto存储结果,并保护该对象不受当前作用域中意外更改的影响,例如,如果对象向上传播的话。
仅仅写一篇文章是非常直观的:
const auto result = RetrieveResult();如果RetrieveResult通过值或引用返回对象,则一切正常。但是,如果函数返回指针,则对指针应用恒定性,而不是对poiter指向的对象应用不变。我还能用什么方式改变对象。写作
const auto const result = ....编译错误的结果:
复本“const”
当然,我可以这样声明变量: const *.康斯特汽车*康斯特。
但这种方式将我与指针紧密联系在一起,也就是说,它不是一个普遍的解决方案。
是否有可能保持真正的稳定性,同时提供灵活性(具体类型的独立性)?
发布于 2017-06-19 14:51:17
这个实用工具叫做std::propagate_const,在图书馆基本原理v2中有实验支持。您可以在此基础上编写一个类型特征(如果您没有std::propagate_const,可以考虑自己编写它:)
namespace {
template <typename T, typename = std::enable_if_t<true>>
PropagateConst {
using type = T;
};
template <typename T>
PropagateConst<T, std::enable_if_t<std::is_same<
decltype(*std::declval<std::decay_t<T>>()),
decltype(*std::declval<std::decay_t<T>>())>::value>> {
using type = std::propagate_const_t<std::decay_t<T>>;
};
template <typename T>
using PropagateConst_t = typename PropagateConst<T>::type;
template <typename Type>
decltype(auto) propagate_const(Type&& in) {
return PropagateConst_t<std::add_rvalue_reference_t<Type>>{in};
}
} // <anonymous>
// then use it like this
const auto result = propagate_const(RetrieveResult());请注意,上面的解决方案只检查可能的指针类型中是否存在operator*。您可能会考虑为此编写一个更广泛的测试。
还请注意,这在propagate_const示例中使用了引用折叠,因此在您可能期望省略的情况下至少会发生移动。您可以根据用例对其进行优化。我只是想勾勒出我脑子里的东西。也许这能帮上忙
发布于 2017-06-19 19:13:04
template<class T>
struct very_const_t { using type=T; };
template<class T>
struct very_const_t<T*> { using type=typename very_const_t<T>::type const*; };
template<class T>
struct very_const_t<T&> { using type=typename very_const_t<T>::type const&; };
template<class T>
typename very_const_t<T>::type&&
very_const( T&& t ) { return std::forward<T>(t); }然后:
const auto result = very_const(RetrieveResult());请注意,这可以阻止省略。不过,我不小心阻止移动语义。
这不会将const移动到智能指针中。如果你想要的话:
template<class T, class D>
struct very_const_t<std::unique_ptr<T,D>> { using type=std::unique_ptr<typename very_const_t<T>::type const, D>; };
template<class T>
struct very_const_t<std::shared_ptr<T>> { using type=std::shared_ptr<typename very_const_t<T>::type const>; };将为unique和shared做到这一点。
https://stackoverflow.com/questions/44633383
复制相似问题