Richy
Richy

Reputation: 714

std::mem_fn for a class member won't compile

I am trying to use function pointers to own member functions in my class, using C++11 and MSVC2013.

class MyClass
{
    public:
    // ...
    QColor Colorize(double dValue) const;

private:
    bool m_bUseColor1;
    QColor Color1(double dValue) const;
    QColor Color2(double dValue) const;
};

Implementation

QColor MyClass::Colorize(double dValue) const
{
    auto colorize_func =  m_bUseColor1 ? std::mem_fn(&MyClass::Color1) : std::mem_fn(&MyClass::Color2);

    QColor myColor =  colorize_func(23.3);// FAILS TO COMPILE
}

This gives the following errors:

Error 102 error C2100: illegal indirection C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xrefwrap 311 Error 103 error C2296: '.*' : illegal, left operand has type 'double' C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xrefwrap 311

Any ideas what is going wrong here? I followed the syntax of cppreference mem_fn but obviously there is an error.

Upvotes: 1

Views: 1123

Answers (1)

Niall
Niall

Reputation: 30624

The use of colorize_func(23.3) requires an instance of the class MyClass to compile and run. Not just the argument for the function.

E.g.:

MyClass mc;
// ....
colorize_func(mc, 23.3);

Since the use of colorize_func is already in a member function, you can use this as well.

QColor myColor =  colorize_func(this, 23.3);

Should do it.

The code is all part of the member anyway, it could also be possible to simplify the code to;

QColor MyClass::Colorize(double dValue) const
{
  return (m_bUseColor ? Color1(dValue) : Color2(dValue));
}

A note on std::mem_fn and it's use (quotes from cppreference.com);

Function template std::mem_fn generates wrapper objects for pointers to members, which can store, copy, and invoke a pointer to member. Both references and pointers (including smart pointers) to an object can be used when invoking a std::mem_fn.

In all cases, the first (or only) argument provided to the callable wrapper is a pointer or reference to an instance of the class.

first_argument_type T* if pm is a pointer to member function taking one argument

These requirements are similar to the older std::mem_fun and std::mem_fun_ref and how they were used.

Upvotes: 3

Related Questions