class T {
size_t *pData; // Memory allocated in the constructor
friend T operator+(const T& a, const T& b);
};
T operator+(const T& a, const T& b){ // Op 1
T c; // malloc()
*c.pData = *a.pData + *b.pData;
return c;
}
T do_something(){
/* Implementation details */
return T_Obj;
}
A simple class T with dynamic memory. Consider
T a,b,c;
c = a + b; // Case 1
c = a + do_something(b); // Case 2
c = do_something(a) + b; // Case 3
c = do_something(a) + do_something(b); // Case 4
- Case 1 uses 1 malloc()
- Case 2 uses 2 malloc()
- Case 3 uses 2 malloc()
- Case 4 uses 3 malloc()
We can do better by addiitonally defining,
T& operator+(const T& a, const T&& b){ // Op 2
// no malloc() steeling data from b rvalue
*b.pData = *a.pData + *b.pData;
return b;
}
Case 2 now only uses 1 malloc(), but what about Case 3? do we need to define Op 3?
T& operator+(const T&& a, const T& b){ // Op 3
// no malloc() steeling data from a rvalue
*b.pData = *a.pData + *b.pData;
return b;
}
Further, if we do define Op 2 and Op 3, given the fact that an rvalue reference can bind to an lvalue reference, the compiler now has two equally plausible function definitions to call in Case 4
T& operator+(const T& a, const T&& b); // Op 2 rvalue binding to a
T& operator+(const T&& a, const T& b); // Op 3 rvalue binding to b
the compiler would complain about an ambiguous function call, would defining Op 4 help work around the compiler's ambiguous function call problem? as we gain no additional performance with Op 4
T& operator+(const T&& a, const T&& b){ // Op 4
// no malloc() can steel data from a or b rvalue
*b.pData = *a.pData + *b.pData;
return b;
}
With Op 1, Op 2, Op 3 and Op 4, we have
- Case 1: 1 malloc (Op 1 is called)
- Case 2: 1 malloc (Op 2 is called)
- Case 3: 1 malloc (Op 3 is called)
- Case 4: 1 malloc (Op 4 is called)
If all my understanding is correct, we will need four function signatures per operator. This somehow doesn't seem right, as it is quite a lot of boilerplate and code duplication per operator. Am I missing something? Is there an elegant way of achieving the same?
Aucun commentaire:
Enregistrer un commentaire