C视图类型:传递const和或值?

最近在代码审查讨论中出现,但没有令人满意的结论。所讨论的类型是类似于C string_view TS。它们是围绕指针和长度的简单的非拥有包装器,用一些自定义函数装饰:

#include <cstddef>

class foo_view {
public:
    foo_view(const char* data, std::size_t len)
        : _data(data)
        , _len(len) {
    }

    // member functions related to viewing the 'foo' pointed to by '_data'.

private:
    const char* _data;
    std::size_t _len;
};

问题出现了是否有一个参数要么通过值或通过const引用喜欢传递这样的视图类型(包括即将到来的string_view和array_view类型)。

有利于值传递的参数等于“减少打字”,“如果视图具有有意义的突变,可以改变本地副本”,以及“可能不低效”。

有利于pass-by-const-reference的参数等于’更常用于通过const&’传递对象,和’可能不低效’。

是否有任何额外的考虑,可能摆动的参数最终决定性的一种方式或另一方面是否更好的通过值或const引用的惯用的视图类型。

对于这个问题,可以安全地假设C 11或C 14语义,以及足够现代的工具链和目标体系结构等。

当有疑问时,传递值。

现在,你应该很少有疑问。

通常价值观通过是昂贵的,并且没有什么好处。有时你实际上想要一个引用一个可能突变的值存储在别处。通常,在通用代码中,你不知道复制是否是一个昂贵的操作,所以你错过不是。

当你怀疑时,你应该通过价值的原因是因为价值更容易推理。外部数据的引用(甚至const引用)可能会在算法中间变异,当你调用函数回调或你有什么,渲染似乎是一个简单的函数复杂的混乱。

在这种情况下,您已经有一个隐式引用绑定(正在查看的容器的内容)。添加另一个隐式引用绑定(到查看容器的视图对象)并不容易,因为已经有并发症。

最后,编译器可以比值更好地引用值。如果你离开本地分析的范围(通过函数指针回调),编译器必须假定存储在const引用中的值可能已经完全改变(如果它不能证明相反)。自动存储中的值,没有人获取指向它的指针可以被假定为不以类似的方式修改 – 没有定义的方式来访问它并且从外部范围改变它,因此这样的修改可以被假定为不发生。

当您有机会将值作为值传递时,拥有简单性。它只发生很少。

相关文章
相关标签/搜索