This is due to how they are defined in the C ++ 11 standard. Clause 23.3.6.1 indicates their signature:
template <class... Args> void emplace_back(Args&&... args); void push_back(const T& x); void push_back(T&& x);
As long as the available overloads for push_back() do not have volatile qualifications, the template argument to the emplace_back() function can be associated with lvalues ββwith any cv -qualification.
However, emplace_back also accepts a link (rvalue-reference links). Why is this happening differently?
Yes, since emplace_back() is a function template, and type inference prints Args as a package of arguments of length one, whose only element is of type int volatile& (see clause 14.8.2.1/3).
The overloads of push_back() , on the other hand, are regular member functions of the template of the std::vector<> class, and when they are called, no type inference occurs. Since references to non- volatile cannot communicate with objects qualified as volatile (see Section 8.5.3 / 4-5), the compiler will not be able to resolve the call.
source share