首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自动和对象恒恒性

自动和对象恒恒性
EN

Stack Overflow用户
提问于 2017-06-19 14:34:39
回答 2查看 273关注 0票数 3

想象一下某个函数(RetrieveResult),通过指针/引用/值返回一个对象--我不知道也不想知道,因为事情可能会变。我只想使用auto存储结果,并保护该对象不受当前作用域中意外更改的影响,例如,如果对象向上传播的话。

仅仅写一篇文章是非常直观的:

代码语言:javascript
复制
const auto result = RetrieveResult();

如果RetrieveResult通过值或引用返回对象,则一切正常。但是,如果函数返回指针,则对指针应用恒定性,而不是对poiter指向的对象应用不变。我还能用什么方式改变对象。写作

代码语言:javascript
复制
const auto const result = ....

编译错误的结果:

复本“const”

当然,我可以这样声明变量: const *.康斯特汽车*康斯特。

但这种方式将我与指针紧密联系在一起,也就是说,它不是一个普遍的解决方案。

是否有可能保持真正的稳定性,同时提供灵活性(具体类型的独立性)?

EN

回答 2

Stack Overflow用户

发布于 2017-06-19 14:51:17

这个实用工具叫做std::propagate_const,在图书馆基本原理v2中有实验支持。您可以在此基础上编写一个类型特征(如果您没有std::propagate_const,可以考虑自己编写它:)

代码语言:javascript
复制
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示例中使用了引用折叠,因此在您可能期望省略的情况下至少会发生移动。您可以根据用例对其进行优化。我只是想勾勒出我脑子里的东西。也许这能帮上忙

票数 4
EN

Stack Overflow用户

发布于 2017-06-19 19:13:04

代码语言:javascript
复制
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); }

然后:

代码语言:javascript
复制
const auto result = very_const(RetrieveResult());

请注意,这可以阻止省略。不过,我不小心阻止移动语义。

这不会将const移动到智能指针中。如果你想要的话:

代码语言:javascript
复制
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>; };

将为uniqueshared做到这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44633383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档