0

I have the following class:

class A {
     B m_data;
};

Also I have a function which needs B& as an argument.

How do I implement a conversion operator that can cast from const A& to B&?

I tried the following (derived from here):

operator B() const { return m_data; }

But that does not work, it says "no matching function call" when I want to call the function which needs B&.

EDIT: To clarify for what I am doing this: I use OpenCV and have implemented a Image class which is a wrapper for cv::Mat. I want to call cv::calcOpticalFlowSF which takes cv::Mat& as input and I have a const Image&.

EDIT2: It should look like this:

const Image OpticalFlowSF::getFlowImage(const Image & in1, const Image & in2) {
    Image flow;
    cv::calcOpticalFlowSF(in1, in2, flow, m_layers, m_averagingBlockSize, m_maxFlow);
    return flow;
}
Community
  • 1
  • 1
gartenriese
  • 4,131
  • 6
  • 36
  • 60
  • @dyp: I tried your suggestion but the same error occurs. I want to use a conversion operator because A is a simple wrapper for B and I don't want to call a function every time. – gartenriese Aug 04 '14 at 11:55
  • You have some kind of design flaw there. What do you want to do? It's not clear from the generic names A, B, data. If you return a non-const ref, you can change that and thus you can change A. Therefore doing that on a const object is not possible without some "trickery", i.e. const_casts or declaring it mutable. What is best depends on your use-case. – dornhege Aug 04 '14 at 11:57
  • @dornhege: I added my use case to my post. – gartenriese Aug 04 '14 at 12:01
  • If you are absolutely sure that the function won't alter the input images a const_cast would be OK. However, are you sure that wrapping a `cv::Mat` is a good idea? I'm not sure that it is. – dornhege Aug 04 '14 at 12:29
  • In this case very specific to `cv::Mat` pass by value is also an option. The image pointer internal to `cv::Mat` is not copied in that case. – dornhege Aug 04 '14 at 12:33
  • @dornhege: Yes, I use pass by value for the time being. Thanks. – gartenriese Aug 04 '14 at 12:50

1 Answers1

3

You can't (safely) returning B& from const A (you may use a const_cast...)
You can returning B& from A and/or const B& from const A.

class A {
public:
    /* explicit */ operator const B&() const { return m_data; }
    /* explicit */ operator B&() { return m_data; }

    // Avoid that
    // operator B&() const { return const_cast<A*>(this)->m_data; }

    // simple getter.
    const B& getB() const { return m_data; }
    B& getB() { return m_data; }

private:
     B m_data;
};

BTW, a simpler getter seems more appropriate in most case.

You may use it that way:

A a;

B& b1 = a; // would not work if uncomment the explicit keyword.
B& b2 = a.getB();
B& b3 = statitc_cast<B&>(a);
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • So there is no way without a getter? – gartenriese Aug 04 '14 at 12:07
  • @gartenriese: I presented several ways: getter with `getB`, implicit conversion with `operator B&` and in comment the conversion with the `const_cast` if really you want to return a non-const reference from a const object. – Jarod42 Aug 04 '14 at 12:15
  • The implicit conversions don't work for const A& to B& though, right? – gartenriese Aug 04 '14 at 12:22
  • As this, no. You have to comment current `operator B&` and uncomment the one I said to not use to have the conversion `const A` -> `B&` possible, as it brokes *constness* contract. – Jarod42 Aug 04 '14 at 12:29