使用 enable_if 检查成员是否存在

新手上路,请多包涵

这是我正在尝试做的事情:

 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
} ;

我见过使用 enable_if例子,但我不明白如何将 enable_if 应用到这个问题上,或者它是否可以应用。

原文由 bobobobo 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 513
2 个回答

使用 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
    }
};

注意事项:

  • 您可以在 decltypesizeof 中命名非静态数据成员,而无需对象。
  • 您可以申请扩展 SFINAE。基本上可以检查任何表达式,如果在替换参数时它无效,则忽略模板。

原文由 Johannes Schaub - litb 发布,翻译遵循 CC BY-SA 3.0 许可协议

您需要一个元函数来检测您的成员,以便您可以使用 enable_if 。这样做的成语称为 Member Detector 。这有点棘手,但可以做到!

原文由 ltjax 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题