Advice on std::forward is generally limited to the canonical use case of perfectly forwarding function template arguments; some commentators go so far as to say this is the only valid use of std::forward. But consider code like this:
// 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_;
};
In this case, the issue of perfect forwarding does not arise: since this is a class template rather than a function template, client code must explicitly specify T, and can choose whether and how to ref-qualify it. By the same token, the argument to std::forward is not a "universal reference".
Nonetheless, std::forward appears to be a good fit here: we can't just leave it out because it wouldn't work when T is a move-only type, and we can't use std::move because it wouldn't work when T is an lvalue reference type. We could, of course, partially specialize ValueHolder to use direct initialization for references and std::move for values, but this seems like excessive complexity when std::forward does the job. This also seems like a reasonable conceptual match for the meaning of std::forward: we're trying to generically forward something that might or might not be a reference, only we're forwarding it to the caller of a function, rather than to a function we call ourselves.
Is this a sound use of std::forward? Is there any reason to avoid it? If so, what's the preferred alternative?
 
     
     
    