std :: forward with copy-on-write分支

时间:2014-10-13 17:47:14

标签: c++ perfect-forwarding

我正在尝试为

的效果做些什么
template <typename T>
void somemethod (T&& t) {
    foo(static_cast<const T&>(t));
    bar(std::forward<T>(t));
}

这样

  1. 如果foo()t进行了更改,则会对副本进行操作。 (类似于写时复制)

  2. foo()完成t后,t会直接转发至bar()

  3. 这可能吗?写的是正确的吗?编译器会理解我想要做什么吗?

    我是否需要制作一些帮助类来实现它?

    同样,如果我尝试了以下效果:

    template <typename T>
    void somemethod (T&& t) {
        foo(std::forward<T>(t));
        bar(std::forward<T>(t));
    }
    

    这样

    1. 然后将t使用的foo()转发给bar()

2 个答案:

答案 0 :(得分:0)

Copy-on-write是类的属性,没有什么好办法可以在somemethod中导致这种情况发生。您可以阻止foo意外修改参数,方法是为其提供const参数,但您还要将其作为参数传递给一个rvalue,这是不必要的,而且很奇怪。我从未见过const T&&的用例。人们使用const T&T&T&&。在您的情况下,我建议const T&

template<class T> //I'm assuming you forgot to paste this bit
void somemethod (T&& t) {
    foo(static_cast<const T&>(t));
    bar(std::forward<T>(t));
}

如果确实想要绝对确定foo在任何情况下都无法t,那么您可以给它一份t而不是const参考,但对任何理智的情况来说都是过度杀伤。

答案 1 :(得分:0)

这个问题可能有更好的解决方案,但你可以做到

template <typename T>
void somemethod (T&& t) {
    T tmp_t = foo(std::forward<T>(t));
    bar(std::forward<T>(tmp_t));
}

甚至更简单:

template <typename T>
void somemethod (T&& t) {
    bar(foo(std::forward<T>(t)));
}

这样foo有办法报告它是否真的改变了什么,但它的签名必须改变:

template <typename T>
T foo(T&& t){
    if (want_to_modify){
        T result;
        // here you insert data that get modified form t
        return std::forward<T>(result);
    }else{
        return std::forward<T>(t);
    }
}

}

这样,T的实例如果没有修改,就会通过foo传递。

其他方式,就是直接在T上实现copy-on-write,但是如果你在使用T的地方不需要它,这可能是一个更好的解决方案