Using std::tr1::bind with std::vector::push_back

后端 未结 4 815
孤独总比滥情好
孤独总比滥情好 2021-01-21 15:39

Why my VS2010 can\'t compile this code:

#include 
#include 
int main()
{
    std::vector vec;
    std::bind(&std::         


        
4条回答
  •  北荒
    北荒 (楼主)
    2021-01-21 16:16

    The bottom line is that what you're trying to do isn't possible in portable C++. std::vector<>::push_back is guaranteed to be overloaded in C++11 compilers, as at a minimum there must be an overload for lvalues and an overload for rvalues.

    Usually, when taking the address of an overloaded member function, §13.4/1 in the C++11 FDIS tells us that we can control which overload we're taking the address of thusly:

    A use of an overloaded function name without arguments is resolved in certain contexts to a function, a pointer to function or a pointer to member function for a specific function from the overload set. A function template name is considered to name a set of overloaded functions in such contexts. The function selected is the one whose type is identical to the function type of the target type required in the context. [ Note: That is, the class of which the function is a member is ignored when matching a pointer-to-member-function type. —end note ] The target can be

    • an object or reference being initialized,
    • the left side of an assignment,
    • a parameter of a function,
    • a parameter of a user-defined operator,
    • the return value of a function, operator function, or conversion,
    • an explicit type conversion, or
    • a non-type template-parameter.

    The overloaded function name can be preceded by the & operator. An overloaded function name shall not be used without arguments in contexts other than those listed. [ Note: Any redundant set of parentheses surrounding the overloaded function name is ignored. —end note ]

    The problem comes from §17.6.5.5/2:

    An implementation may declare additional non-virtual member function signatures within a class by adding arguments with default values to a member function signature; hence, the address of a member function of a class in the C++ standard library has an unspecified type.

    Consequently, it is not portable to ever take the address of a standard library class member function, as the type of such an expression is by definition unknowable except on an implementation-by-implementation basis.

    Luc Danton's proposed workaround (specifically, using a lambda) is also what I would recommend:

    std::vector vec;
    [&](){ vec.push_back(1); }();
    

提交回复
热议问题