1

I have an object that has a mathematical function behind it. It seems like a perfect candidate for operator().

Specifically its a light that has a different value for each (phi,theta) position on the sphere.

Now the thing is, when inside the class, accessing the light function has this crunky syntax:

 double operator() ( double phi, double theta ) { // compute light function return sin(2*t) * cos(p) ; // (really this is implemented as a function pointer, // so the light function can be changed) } void functionThatUsesLightFunction() { double val = ( 2.0, 4.0 ) ; // seems bad // Whoops! Doesn't work. double val2 = (*this)( 2.0, 4.0 ) ; // ok double val3 = operator()( 2.0, 4.0 ) ; // no thank you } 

But from outside the class, it gets this really nice syntax like

 foreach( theta on 0..PI ) foreach( phi on 0..2*PI ) val += light( theta, phi ) ; 

Do you think I'm misusing operator() here?

4
  • 3
    Can't you define a (private?) method compute(bla) and call it inside operator()? Then you can call compute inside the class and use the operator() outside. Commented Aug 12, 2011 at 20:01
  • 4
    The first mechanism does not invoke operator(). Commented Aug 12, 2011 at 20:03
  • I'm not a fan of operator(). Operator() is a method with no name: It is the emperor's new method (as in the emperor's new clothes). operator() looks just as ugly and just as naked from the outside as it does from the inside. What is wrong with a fully clothed function here, such as illumination? Commented Aug 12, 2011 at 20:12
  • 5
    @David: operator() doesn't look at all ugly if you want to create an object that acts like a function. I agree that it makes very little sense if it's only for "internal" use, though. Commented Aug 12, 2011 at 20:17

3 Answers 3

5

i think you should define yet another function, say calculate, in the private section of the class, and call this function from operator() and other member functions. That way, you wouldn't be calling operator() from member functions, but you can still call it from outside the class. Somthing like this:

class Light { private: double calculateLight( double phi, double theta ) { return sin(2*t) * cos(p) ; } public: double operator() ( double phi, double theta ) { return calculateLight(phi, theta); } //... void functionThatUsesLightFunction() { double val3 = calculateLight( 2.0, 4.0 ); } }; //Outside the class Light light; //... val += light( theta, phi ) ; 

There is also a good advantage in adding calculateLight function, as you can choose a good name for this function, which increases readability. operator() adds nothing to the readability.

Sign up to request clarification or add additional context in comments.

3 Comments

I wouldn't recommend that for a simple reason to avoid duplication, both readability and maintainability suffers. Later somebody will decide to add/change functionality of operator() and they forget that calculate() is actually a synonym. There is nothing wrong or difficult about (*this)() or operator()(), they are quite readable, and not at all burdensome.
@Gene: Where is the duplication?
The duplication is that what if someone came along and changed operator() to be: return calculateLight(phi, theta) * 2;. Then functionThatUsesLightFunction would be doing something different than operator() when they should probably be using the same code.
1

I don't see why you would use operator() here. You don't access any object fields in the body of operator() and neither you change object state. I'd rather create a static method or just a regular function...

3 Comments

This is really acting as a function object. The OP says that in practice, operator() will invoke a function via a function pointer, which will presumably be a member variable. That sounds like a very reasonable use of operator().
@Oli Charlesworth: You are absolutely right from OP perspective, but I don't think this is the case where OP approach must be applied... For example, sin is just a function, not class sin with operator() (double val)...
@a1ex07: but as Oli said, see the questioner's comment, "really this is implemented as a function pointer, so the light function can be changed". In fact the operator() does access a data member. So you need to explain how a free function should replace this member function whose output depends on the current state of the object.
0

YourClass::operator() as in a.operator() (arguments) as opposed to a(arguments) is pretty fine. It's just a matter of getting used to. Use it for a while, together with the C++ style casts, it will make you feel more pedantic and you won't be bothered by it afterwards.

1 Comment

Use Haskell then :). But don't feel that valid C++ is ugly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.