tags:

views:

751

answers:

5

I am writing a library in standard C++ which does the phonetic conversion. I have used std::string as of now. But in future I may have to change this to someother (std::wstring or something else). So I need to write my library in such a way that I can switch this easily. I have done the following so far to achieve this.

  1. Created a header file which will be used by all CPP files
  2. Added a "typedef std::string" to this and used the new name everywhere in the file.

If I need to change the type, I can simply change in the header file and it will be reflected everywhere. I'd appreciate if someone can see this is the correct approach or is there a better way to do this?

Thanks

A: 

I would create a class that has a std::string as a private member. You would then need to reimplement the methods that you want to use, but if you switch the string type in the future all you would need to do is rewrite this class.

The typedef would work fine for switching from string to wstring, but switching to a string class with a different interface would not be very easy (ie. qstring).

CTT
A: 

This will work so long as whatever you replace std::string with in the future has all of the same methods, constructors etc as std::string. For example, this won't work to with std::wstring because its methods operate on wide characters rather than char.

If you're really planning on swapping out the type in the future, it is probably a good idea to encapsulate your data in a custom class with the required interface to begin with and then change out the implementation while leaving the interface the same. std::string is probably too "primitive" for your application.

Dave Ray
+4  A: 

You can write template functions that will work with either type of string, or for that matter anything that has the proper methods.

If you do the typedef as you suggest, you will need to change all your code in the future when you change the typedef. I'd recommend against it.

Edit: the point is that string and wstring are not interchangeable. Sure, you'll be able to update your library by changing a single line, but that's just the start - changing the typedef means you're changing the public API of your library. You'll have to change and test all of the code that interacts with your library, and this might represent the majority of the work involved. It's even possible that a simple search and replace is sufficient to update your library, and then the typedef has bought you nothing.

There's value in sticking to the standard types that everyone knows and understands.

Mark Ransom
Thanks. How creating a new class which is derived from std::string? If I need to change to another totally different type, I can change the inheritance and provide necessary interface methods to this custom class and it can be done with minimum effort. What do you say?
Appu
hmm. i don't understand why the template approach is better here than the typedef. i mean, if he changes the type, he just changes his typedef - that was the reason he wanted to introduce it after all.
Johannes Schaub - litb
@Appu: deriving from std::string is non-trivial if you want your code to be portable. The reason is that STL implementers are allowed to add any optional template parameters to std::string they see fit.
wilhelmtell
ah, you mean if he changes the typedef name itself. hmmm i guess one could always find reasons to use something or not. templates have their own issues. given that his code will work always with one type at the time (the used string type), i think templates are overkill here imho.
Johannes Schaub - litb
a similar argument is - you can change the name of the template parameter in the class definition, or the typedef making it available to outside. and you would have to change all the code places using it. i think that problem is not a particular flaw of his typedef approach, but it exist generally.
Johannes Schaub - litb
yeah. i think that typedefs in general exist exactly for this purpose, to abstract type names so you can change type references easily. of course, they don't solve the interface problem.
wilhelmtell
So what is the conclusion? typedef or custom classes? Thanks
Appu
string and wstring aren't interchangeable, but the compiler will tell you were changes are needed. AFAIK there are no automatic conversions between char and wchar_t types, so the thing would remain typesafe. That's why I would agree on using a typedef for starters, and migrate to a proper class -
xtofl
when needed. (darn, 300 chars is a little small.)
xtofl
+2  A: 

I think typedeffing std::string is reasonable. You are still bound to an interface though. If you ever switch to a string implementation with an incompatible interface you can change the value of your typedef to some adapter class. In C++, you can do this with minimal to no overhead. Changing to a new string type then implies changing the adapter class. If you find yourself changing the adapter often you might set it as a template.

You are still not immune however from others (or yourself in a later time) forgetting about the typedef and using std::string directly.

wilhelmtell
A: 

If you expect the string needs to change in the future, It's good practice to abstract it away from the rest of the code.

Typedef or dedicated class are both ways to accomplish this.

Using a typedef is a good start: the code relies on an abstraction. The thing is: your client code can use anything a std::string offers, so if you want to migrate later, you will have to analyse post-factum what aspects are needed (if you don't want to mimic the whole std::string).

If you want to keep control on what the client code can use, you are better of using a proper class with a more limited interface.

So: know your needs and decide.

xtofl