Hey guys,

How would I partially specilize a template in a manner as below? Is that even possible?

I have these two functions:

bool node::read(const char *filename) {
    ifstream f(filename);

    if (!f.good()) return false;

    bool success = read(f);
    f.close();

    return success;
}

bool node::write(const char *filename) {
    ofstream f(filename);

    if (!f.good()) {
        return false;
    }

    bool success = write(f);
    f.close();

    return success;
}

And I'd like to create a function like this:

template <typename T>
bool node::read_or_write(const char *filename) {
    T f(filename);

    if (!f.good()) {
        return false;
    }

    bool success;
    if(T == ifstream){
        success = write(f);
    } else if (T == ofstream){
        success = read(f);
    }
    f.close();

    return success;
}

How would I do that?

Thanks in advance,

Well, a design wouldn't need it. I don't know if its needed but can't you say something like: T can only be ifstream, ofstream

Code could look a bit like this:

template <typename T = {ifstream, ofstream}>
bool node::read_or_write(const char *filename) {
    T f(filename);

    if (!f.good()) {
        return false;
    }

    bool success;
    if(T == typename ifstream){
        success = write(f);
    } else if (T == typename ofstream){
        success = read(f);
    }
    f.close();

    return success;
}

Compiler should throw an error when you try to instantiate any other type of it.. I'm trying to create such a class now, but I'm not very good at it.

This is the best I could come up with, but I didn't compile/test it yet due to diner being ready.

template <typename T>
class filestuffs {
    filestuffs(const char *filename) : filename(filename) {
        f(filename);
        success = f.good();
        success = read_or_write();
        f.close();
    }
    
    //can't do this unless we know T
    bool read_or_write(){ return false; }
            
    T f;
    bool success;
    const char *filename;
    const char [] errmsg = "Can't do this on anything but: ifstream, ofstream";
}
template <>
class filestuffs<ifstream> {
    //now we know T! :D
    bool read_or_write(){
        return read(f);
    }
}

template<>
class filestuffs<ofstream> {
    bool read_or_write(){
        return write(f);
    }
}

Oh I'm sure that doesn't work, never seen it, just made it up. But I want to know how I'd do that in C++. :D

I am not looking for a runtime solution, that's why I hadn't.

Here's a working example:

template <typename T>
        bool read_or_write(const char *filename) {
            T f(filename);
            if (!f.good()) {
                return false;
            }

            bool success;
            if (typeid(T) == typeid(ofstream)) {
                success = write(f);
            } else if (typeid(T) == typeid(ifstream)) {
                success = read(f);
            }
            f.close();

            return success;
        }

But this way, I also have to define write(ifstream ... ), while I know 100% sure that the compiler will never have to call such a function. It kinda defeats it's use (making the code smaller) for this small function, but for bigger functions this sort of template is very usable I think.

Any compiler-time suggestions?

PS: For anyone reading this and thinking, why the hell are you creating such a function for 20 lines of code? It's because I'm not going to use read_or_write(), but would like to know how I'd accomplish maximum code re-usage in C++.

Why are you using two separate functions read and write then ?

Because one reads and one writes? Hahahaha

Because one reads and one writes? Hahahaha

Of course :), but I asked why you SEPERATED these from your function, why not implement them directly in your function ?

Ah, sorry. They are big functions. :) I finished the code and documented it, it's for review at my website, here's a quick link:

www.dotsimplicity.net/?p=191

Thanks for your input! That typeid() will come in handy one day.

This question has already been answered. Start a new discussion instead.