jeudi 23 février 2017

Stop implicit casting for C++98 and C++11

I have a templated class with a get() method which returns the type it is templated on. There's a bit more to it than that, but for simplicity the code looks something like:

Attribute<float> attr(0.0f);
float value = attr.get();

However, the following will also compile:

Attribute<float> attr(0.0f);
int value = attr.get();

I want the compiler to catch that, and tell me that I have an illegal conversion. A simple way of doing that is to create a new Holder<T> class which has a conversion operator to the type that it's templated on. The get method would work as follows:

template<typename T>
Holder<T> Attribute::get()
{
    return Holder<T>(m_value);
}

With the Holder class looking something like:

template<typename T>
class Holder {
    private:
        T m_value;
    public:
        Holder(T value) : m_value(value)
        //implicit conversion
        operator T() const { return m_value; }
};

(I've written this just in the editor and haven't tested it, but that should work-ish to do what I want in C++98)

Attribute<float> attr(0.0f);
// This should now not compile because we have no conversion from
// Holder<float> to int.
int value = attr.get();

The tricky bit comes when we move to C++11, I probably want to use auto, and suddenly, when I do:

Attribute<float> attr(0.0f);
auto value = attr.get();

value will now be of type Holder<float> which I don't want. Can anyone think of a way of allowing both to work, perhaps with some boost magic.

Aucun commentaire:

Enregistrer un commentaire