check if member exists using enable_if

前端 未结 6 1305
鱼传尺愫
鱼传尺愫 2020-11-28 13:40

Here\'s what I\'m trying to do:

template  struct Model
{
    vector vertices ;

    #if T has a .normal member
    void transform(         


        
6条回答
  •  伪装坚强ぢ
    2020-11-28 13:45

    I know this question already has some answers but I think my solution to this problem is a bit different and could help someone.

    The following example checks whether passed type contains c_str() function member:

    template 
    struct has_c_str : false_type {};
    
    template 
    struct has_c_str> : std::is_same().c_str())>
    {};
    
    template ::value, StringType>::type* = nullptr>
    bool setByString(StringType const& value) {
        // use value.c_str()
    }
    

    In case there is a need to perform checks whether passed type contains specific data member, following can be used:

    template 
    struct has_field : std::false_type {};
    
    template 
    struct has_field> : std::is_convertible
    {};
    
    template ::value, T>::type* = nullptr>
    void fun(T const& value) {
        // use value.field ...
    }
    

    UPDATE C++20

    C++20 introduced constraints and concepts, core language features in this C++ version.

    If we want to check whether template parameter contains c_str member function, then, the following will do the work:

    template
    concept HasCStr = requires(T t) { t.c_str(); };
    
    template  
    void setByString(StringType const& value) {
        // use value.c_str()
    }
    

    Furthermore, if we want to check if the data member, which is convertible to long, exists, following can be used:

    template
    concept HasField = requires(T t) {
        { t.field } -> std::convertible_to;
    };
    
    template  
    void fun(T const& value) {
        // use value.field
    }
    

    By using C++20, we get much shorter and much more readable code that clearly expresses it's functionality.

提交回复
热议问题