mardi 20 février 2018

Enforce compile time check during initialization of non-integral types

I am trying to make sure that variables are initialized with valid data and would like to have this check carried out at compile time. The classes have a static constexpr to check validity. In a simplified version it could be like this:

template <typename T>
struct Foo {
    constexpr Foo(T initValue) :
      mValue(initValue) 
    {
         assert(isValid(iniValue));
    }

    static constexpr bool isValid(T value) {
        return (value > 0);
    }        
private:
    T mValue;
};

Now for integral types I could use a templated function to enforce compile time checks:

template <typename T, T initVal>
Foo<T> make_new() {
    static_assert(Foo<T>::isValid(initVal), "is not valid");
    return  Foo<T>(initVal);
}

And use it like this

    auto saveInt = make_new<int, 3>();

The question is how to do that with non-integral types. I could do something like this which would trigger the assert in C++14:

    constexpr Foo<float> constFloat(3.0);
    Foo<float> saveFloat = constFloat;

Is there a maybe a more elegant way in C++>=11 which would allow me to do that with a one-liner? In the end the value I want to assign is known at compile time and so is the validity of this value.

Aucun commentaire:

Enregistrer un commentaire