Take the 2-minute tour ×

I'm using visitor pattern to define a set of operations on some classes.
Some operations are commutative, so I end up with duplication in the visitor pattern code.
Let's say I have classes A B C, and the operations: A*A, A*B, A*C, B*A, B*B, B*C, C*A, C*B, C*C.
A*A, B*B, C*C are unique.
A*B, B*A and friends will have code duplication I could implement A*B, and make B*A call A*B but I will end up asking myself: in which file did I implement the operation between A and B again, in A or in B? (there will be about 6 classes, so I will ask this question a lot. 15 pairs of possible operations)
There is a risk of someone in the future making an infinite loop of A*B calling B*A calling A*B when implementing a new operation.
It's unnatural to have a convention that decides which should be implemented A*B or B*A.
I could make a 3rd file with all the implemented functions which are called by either A*B and B*A, doesn't seem very object oriented.
How would you solve this issue?
(I could list some code, but it's long and doesn't illustrate the point easily)

share|improve this question

2 Answers 2

up vote 3 down vote accepted

You are right, you should definitely refrain from implementing A*B as a call of B*A. In addition to a potential of creating an infinite chain of calls, that approach does not reflect the symmetry of the operation in your code, because the code is not symmetric.

A better approach is to implement a "symmetric" operation in a helper class or as a top-level function, depending on what is supported in your language, and then make both A*B and B*A call that helper implementation.

share|improve this answer
there is a guideline that it's not exactly ok for class to use the attributes of other classes. I guess there isn't much of a choice –  titus Aug 18 '12 at 15:35
Scott Meyer has an excellent discussion on the topic in his More Effective C++ book (Item 31: Making functions virtual with respect to more than one object.) His example is making a collision function for a game where various objects may collide in space. His example is symmetric too (it does not matter if an asteroid hits a spaceship or a spaceship hits an asteroid, the explosion is the same). He starts with a visitor pattern, and gradually works out a C++ - specific solution that relies on RTTI. –  dasblinkenlight Aug 18 '12 at 15:40
is this in the 1996 edition? –  titus Aug 18 '12 at 16:11
@titus I am pretty sure that it is (I read that book in 1997, and the item was there). –  dasblinkenlight Aug 18 '12 at 16:31
I tried to implement with RTTI, I used typeid().name(), it was very slow, then I tried making a static function for each subclass that returns an int, this is one of the indexes in a function pointer matrix . It's still 3x slower than the visitor pattern. Here is the repository github.com/titusnicolae/comparison/blob/master/rtti.cpp –  titus Aug 23 '12 at 15:45

My suggestion would be use builder which will act as parameter Builder

new ParameterBuilder()
    .setFirst( "A" )
    .setSecond( "B" )
    .setThird( "C" )

Then you will have only one method which takes ParameterBuilder as argument.

share|improve this answer
hmm, I could implement stuff as Object* result = new MultiplyHelper().addOperand("A").addOperand("B").compute(); –  titus Aug 18 '12 at 15:54
I also have some non-commutative functions such A/B, using a symmetric construct as the above one for a non-symmetric operation is not ok. Better the other way around. –  titus Aug 18 '12 at 16:00
Parameter builder is just for taking parameters what you do with them is up to you. What your doing is also good. I suggested this solution to keep your methods intact and only change method signature. –  Amit Deshpande Aug 18 '12 at 16:02

Your Answer


