1

I'm trying to implement a manipulator with one integer argument. Except for one little difference I think I'm doing exactly what is told in this guide and in this question. The only difference is that my operator is a member instead of a free function.

I'll put here just the relevant parts of my code. Some operators and other internal routines will be omitted to keep the code clean. See below:

main.cpp

#include "Display.h"

int main()
{
    Display disp;
    disp << position(3) << "some string here";
    // ...
}

Display.h

struct manip
{
    Display& (*_f)(Display&, int);
    int _i;
    manip(Display& (*f)(Display&, int), int i) : _f(f), _i(i) {}
};

manip position(int pos);

class Display 
{
private:
    int _cursor = 0;
    void cursorPosition(int pos);
public:
    Display& operator<<(manip& m);
    friend Display& setPosition(Display& disp, int pos);
};

Display.cpp

#include "Display.h"

Display& setPosition(Display& disp, int pos)
{
    disp.cursorPosition(pos);
    return disp;    
}

manip position(int pos)
{
    return manip(setPosition, pos);
}

Display& Display::operator<<(manip& m)
{
    return m._f(*this, m._i);
}

The compiler is returning this error message:

"no match for 'operator<<' (operand types are 'Display' and 'manip')"

Can someone tell me what am I doing wrong?

Community
  • 1
  • 1
  • you can replace `Display& operator<<(manip& m);` by `Display& operator<<(const manip& m);`. `position` returns a xvalue and there are no default conversion to a lvalue. – Franck Nov 13 '16 at 16:36
  • Yeah! You and Sam are right. Thanks! –  Nov 13 '16 at 16:45

1 Answers1

1
 disp << position(3) << "some string here";

position(3) returns a temporary manip object, here.

Your overloaded << operator is declared as follows:

 Display& operator<<(manip& m);

Only a const reference can bind to a temporary object. A non-const reference will not bind to a temporary object. Your << operator should have a const manip & parameter, instead of manip &.

This has nothing to do with manipulators that have a parameter. A manipulator without a parameter that's used the same way will also have the same issue, unless it's declared as a static object in global scope (but, in that case, it should also be a const object, and will have the same issue as well).

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148