views:

96

answers:

3

I'm having a problem getting a program to read from a file based on a template, for example:

bool parse(basic_ifstream<T> &file)
{
    T ch;
    locale loc = file.getloc();
    basic_string<T> buf;
    file.unsetf(ios_base::skipws);
    if (file.is_open())
    {
        while (file >> ch)
        {
            if(isalnum(ch, loc))
            {
                buf += ch;
            }
            else if(!buf.empty())
            {
                addWord(buf);
                buf.clear();
            }
        }
        if(!buf.empty())
        {
            addWord(buf);
        }
        return true;
    }
    return false;
}

This will work when I instantiate this class with <char>, but has problems when I use <wchar_t> (clearly).

Outside of the class, I'm using:

for (iter = mp.begin(); iter != mp.end(); ++iter )
{
    cout << iter->first << setw(textwidth - iter->first.length() + 1);
    cout << " " << iter->second << endl;
}

To write all of the information from this data struct (it's a map<basic_string<T>, int>), and as predicted, cout explodes if iter->first isn't a char array.

I've looked online and the consensus is to use wcout, but unfortunately, since this program requires that the template can be changed at compile time (<char> -> <wchar_t>) I'm not sure how I could get away with simply choosing cout or wcout. That is, unless there way a way to read/write wide characters without changing lots of code.

If this explanation sounds awkwardly complicated, let me know and I'll address it as best I can.

+5  A: 

Use a traits class. Instead of referencing directly cout in code, you'd reference traits<T>::cout and then specialize traits<char> to std::cout and traits<wchar_t> to wcout.

Updated

template <typename T>
class traits {
public:
    static std::basic_ostream<T>& tout;
};

template<>
std::ostream& traits<char>::tout = std::cout;

template<>
std::wostream& traits<wchar_t>::tout = std::wcout;

int _tmain(int argc, _TCHAR* argv[])
{
    traits<char>::tout<<"Ascii";
    traits<wchar_t>::tout<<L"Unicode";
    return 0;
}
Remus Rusanu
A: 

Sure, just redefine the templates and use a typedef:

#ifdef USE_UNICODE
typedef wchar_t tchar_t
#else
typedef unsigned char tchar_t
#endif

Then you can use the templates of most standard C++ functions/containers:

typedef std::basic_string<tchar_t> tstring

etc.

Billy ONeal
A: 

Interesting - I'll look into these. Any idea on forcing the input of characters through the file stream?

Mark
Add this as a comment, or an edit to your question. You've posted an "answer".
GMan
Maybe I'm just blind - but I cannot find a "comment" button on any of the answers. The only one that showed up was for your comment. I'm clearly missing it...
Mark
Heh, strange. It's under the trio "link | flag".
GMan
I've just got link | flag on all of the posts except this comment thread...
Mark
Oh, I see the problem. You see, it takes 50 reputation to comment on anything, but one can always comment their own question and answers. The thing is, you've posted this answer in an account different than that of your question.
GMan
Christ. Is there any way to message people directly on here? I'm having trouble with one of the answers (from Mr. Rusanu). Or do I need more reputation before I can do that.
Mark
No PMs, but I voted up the question from your Mark L account so you're 10 points closer to being able to comment on Remus' answer.
Tyler McHenry
Haha this is so painful. Thanks though. Would you happen to know how to specialize using traits?
Mark
@Mark: There isn't any direct messaging possible on SO, but you can detail what your problem is I can look into it. Normally I'd post a code sample to exemplify my post, I just don't have any C++ compiler handy for that next couple of hours.
Remus Rusanu
Ok - well, I guess the only thing I'm wondering at this point is how to actually create a traits class that would overload << and function like cout or wcout. Most of what I've looked at online about traits is for explicit functions (or just to handle a type conversion). Sorry this is such a bother, I've not been on SO before.
Mark
@Mark: gimme a couple of hours and I'll post one from my home computer where I have C++
Remus Rusanu
Ah - thank you very much!
Mark