Search code examples
c++c++11promisefuturepass-by-value

Why does std::promise::set_value() have two overloads


For the case when std::promise<> is instantiated with a non reference type, why does the set_value() method have two distinct overloads as opposed to one pass by value overload?

so instead of the following two

std::promise::set_value(const Type& value);
std::promise::set_value(Type&& value);

just one

std::promise::set_value(Type value);

This has at least the following two benefits

  1. Enable users to move the value into the promise/future when they want, since the API argument is a value type. When copying is not supported it is obvious that the value is going to be copied. Further when the expression being passed into the function is a prvalue it can be completely elided easily by the compiler (especially so in C++17)

  2. It conveys the point that the class requires a copy of the value a lot better and succinctly than two overloads which accomplish the same task.

I was making a similar API (as far as ownership is concerned) and I was wondering what benefits the design decision employed by the C++ standard library has as opposed to what I mentioned.

Thanks!


Solution

  • Passing an argument by value if it needs to be "transferred" unconditionally and then moving from it is a neat little trick, but it does incur at least one mandatory move. Therefore, this trick is best in leaf code that is used rarely or only in situations that are completely under the control of the author.

    By contrast, a core library whose users and uses are mostly unknown to the author should not unnecessarily add avoidable costs, and providing two separate reference parameter overloads is more efficient.

    In a nutshell, the more leaf and user you are, the more you should favour simplicity over micro-optimizations, and the more library you are, the more you should go out of your way to be general and efficient.