It's similar to boost, but more general purpose functions and is much more user friendly. |
IMHO, no, and no. It is not more general purpose than boost. It is not more user-friendly either; it may
be that it is easier to understand for programmers who are not comfortable with templates.
If toupper() is to return a new dynamically allocated string, then you should pass string1 as a
const char*, not a char. But I hardly consider it user-friendly to require the user to free the
memory allocated by toupper().
And since it seems to use iterators and the like and does the operation on each iterator, it can't possibly be more efficient than having my function do the operations in a single lower-level loop
|
This isn't necessarily true. Your algorithm is far from optimal because:
1) You use new, which requires memory to be allocated. This is a linear walk of the heap to find a free block
large enough to suffice the request.
2) You walk the input string linearly once to do strlen().
3) You walk it a second time to do the memcpy().
4) You walk it essentially a third time (albeit the destination string, not the source, but still it walks the same
number of bytes) to perform the upper-case conversion.
Furthermore, using std::transform() can actually be faster thanks to inlining. If the compiler can see the
body of the function when it is compiling the call to std::transform(), the compiler can inline the body of
the function directly inside the std::transform() instantiation, which itself could be inlined in your
function.
Does transform even work on a standard array...?
|
Yes, it does. It works on any input/output iterator type. Pointers match that criterion.
Void and int main makes absolutely no difference, seeing as I am not having the program return a value. All int does is make me need to return a value, which is one line of unneeded code.
|
It makes a difference in that void main() is not C++ standards compliant whereas int main() is. And, thanks
to all the C programmers out there who wrote int main() and then never bothered to write a return statement
in the body of the function, it is legal and compliant to omit the return statement from main(), even if it returns
int. So no, it does not force you to write an extra line of code.
Is there a better method to allocate the memory? Malloc perhaps...?
|
Well, going your route, char* strdup( const char* src ) copies the src string to a newly allocated buffer which is exactly large enough to hold the source string. You could use that in lieu of your own new/memcpy. However
by your standards, more efficient would be to new/malloc the memory, then walk the source string and populate the buffer with the correct characters eg,
1 2 3
|
char* buf = new char[ strlen( src ) + 1 ];
for( size_t i = 0; i < strlen( str ) + 1; ++i ) // + 1 causes us to process the \0 also
buf[ i ] = str[ i ] >= 65 && str[ i ] <= 90 ? str[ i ] + 32 : str[ i ];
| |
You're sending the function character pointers anyways, which means chances are you're already using pointers.
|
Ok, sure, but not every pointer is to heap memory. It is NOT user friendly, no matter how you slice it, to
force the user to remember to free memory your function allocated, regardless of how detailed your
memory manager is.
Making a string v2 class would work ... but it's not as low-level and probably less efficient.
|
Probably less efficient? Hardly. You won't see any difference in execution time between:
1 2 3 4
|
class my_string {
public:
my_string toupper() const;
};
| |
and
|
char* toupper( const char* );
| |