mardi 25 décembre 2018

What is the recommended way to simulate concepts and constraints?

Before the introduction of concepts and constraints, there are several ways to simulate this compile-time check. Take a "order()" function for example: (how to implement LessThanComparable without concepts or constraints is another story)

  • Use static_assert

    template <typename T, typename U>
    void order(T& a, U& b)
    {
        static_assert(LessThanComparable<U,T>, "oh this is not epic");
        if (b < a)
        {
            using std::swap;
            swap(a, b);
        }
    }
    
    

    This approach won't work for function overloading.

  • Use typename = enable_if

    template <typename T, typename U,
        typename = std::enable_if_t<LessThanComparable<U,T>>>>
    void order(T& a, U& b)
    {
        if (b < a)
        {
            using std::swap;
            swap(a, b);
        }
    }
    
    

    What if an over-"intelligent" guy specifies a third parameter by hand?

  • Use enable_if in the function prototype:

    template <typename T, typename U>
    std::enable_if_t<LessThanComparable<U,T>>, void> order(T& a, U& b)
    {
        if (b < a)
        {
            using std::swap;
            swap(a, b);
        }
    }
    
    

    Sometimes also doesn't work in function overloading.

  • Use enable_if as the type of a dummy non-type template parameter

    template <typename T, typename U,
        std::enable_if_t<LessThanComparable<U,T>>, void*> = nullptr> // or int = 0
    void order(T& a, U& b)
    {
        if (b < a)
        {
            using std::swap;
            swap(a, b);
        }
    }
    
    

    I saw this before, and I can't think of any drawbacks.

  • And many other variants.

Which ones are preferable or recommended? What is the benefits and drawbacks? Any help is appreciated.

Aucun commentaire:

Enregistrer un commentaire