c++templatessfinae

check if member exists


Here's what I'm trying to do:

template <typename T> struct Model
{
    vector<T> vertices ;

    #if T has a .normal member
    void transform( Matrix m )
    {
        each vertex in vertices
        {
          vertex.pos = m * vertex.pos ;
          vertex.normal = m * vertex.normal ;
        }
    }
    #endif

    #if T has NO .normal member
    void transform( Matrix m )
    {
        each vertex in vertices
        {
          vertex.pos = m * vertex.pos ;
        }
    }
    #endif
} ;

I've seen examples of using enable_if, but I cannot understand how to apply enable_if to this problem, or if it even can be applied.


Solution

  • This has become way easier with C++11.

    template <typename T> struct Model
    {
        vector<T> vertices;
    
        void transform( Matrix m )
        {
            for(auto &&vertex : vertices)
            {
              vertex.pos = m * vertex.pos;
              modifyNormal(vertex, m, special_());
            }
        }
    
    private:
        
        struct general_ {};
        struct special_ : general_ {};
        template<typename> struct int_ { typedef int type; };
    
        template<typename Lhs, typename Rhs,
                 typename int_<decltype(Lhs::normal)>::type = 0>
        void modifyNormal(Lhs &&lhs, Rhs &&rhs, special_) {
           lhs.normal = rhs * lhs.normal;
        }
    
        template<typename Lhs, typename Rhs>
        void modifyNormal(Lhs &&lhs, Rhs &&rhs, general_) {
           // do nothing
        }
    };
    

    Things to note: