gpt4 book ai didi

c++ - std::forward 没有完美转发?

转载 作者:行者123 更新时间:2023-12-02 03:18:44 25 4
gpt4 key购买 nike

关于 std::forward 的建议通常仅限于完美转发函数模板参数的规范用例; some commentators甚至可以说这是 std::forward唯一有效使用。但考虑这样的代码:

// Temporarily holds a value of type T, which may be a reference or ordinary
// copyable/movable value.
template <typename T>
class ValueHolder {
public:
ValueHolder(T value)
: value_(std::forward<T>(value)) {
}


T Release() {
T result = std::forward<T>(value_);
return result;
}

private:
~ValueHolder() {}

T value_;
};

在这种情况下,完美转发的问题不会出现:由于这是类模板而不是函数模板,客户端代码必须显式指定T,并且可以选择是否以及如何引用- 限定它。同样,std::forward 的参数也不是“通用引用”。

尽管如此,std::forward 似乎很适合这里:我们不能把它排除在外,因为当 T move 时它不起作用-only 类型,并且我们不能使用 std::move 因为当 T 是左值引用类型时它不起作用。当然,我们可以部分专门化 ValueHolder 以对引用使用直接初始化,对值使用 std::move ,但是当 std::时,这似乎过于复杂。 forward 完成了这项工作。这似乎也是与 std::forward 的含义合理的概念匹配:我们正在尝试一般性地转发可能是也可能不是引用的内容,只是我们将其转发给调用者一个函数,而不是我们自己调用的函数。

这是 std::forward 的合理使用吗?有什么理由避免它吗?如果是这样,首选的替代方案是什么?

最佳答案

std::forward 是一个条件 move 转换(或者更技术性的右值转换),仅此而已。虽然在完美转发上下文之外使用它会令人困惑,但如果 move 上的相同条件适用,它可以做正确的事情。

我很想使用不同的名称,即使只是 forward 上的一个薄包装,但我想不出适合上述情况的好名称。

或者使条件 move 更加明确。即,

template<bool do_move, typename T>
struct helper {
auto operator()(T&& t) const
-> decltype(std::move(t))
{
return (std::move(t));
}
};
template<typename T>
struct helper<false, T> {
T& operator()(T&& t) const { return t; }
};
template<bool do_move, typename T>
auto conditional_move(T&& t)
->decltype( helper<do_move,T>()(std::forward<T>(t)) )
{
return ( helper<do_move,T>()(std::forward<T>(t)) );
}

如果 bool 为 false,则为 noop 传递;如果为 true,则为 move。然后,您可以使您的等效于 std::forward 更加明确,并且更少依赖于用户了解 C++11 的神秘 secret 来理解您的代码。

用途:

std::unique_ptr<int> foo;
std::unique_ptr<int> bar = conditional_move<true>(foo); // compiles
std::unique_ptr<int> baz = conditional_move<false>(foo); // does not compile

第三方面,您在上面做的事情需要对右值和左值语义有相当深入的理解,所以也许 forward 是无害的。

关于c++ - std::forward 没有完美转发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20616958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com