【问题标题】:How to define a template function for a reference parameter and the same function for a pointer parameter如何为引用参数定义模板函数和为指针参数定义相同的函数
【发布时间】:2012-05-11 12:05:21
【问题描述】:

我想定义一个用于名称比较的模板仿函数,它也接受引用 作为指针。我想将它用于元素容器上的普通 find_if 以及指针容器(不幸的是 ptr_vector 等不是一个选项)。

目前我发现的最佳解决方案如下。

template <typename U>
class by_name{
  public:
    by_name(U const& pName):mName(pName) {}

    template <class T>
    typename boost::disable_if_c<boost::is_pointer<T>::value, bool>::type
    operator()(T const& pX){ return pX.getName()== mName;}

    template <class T>
    typename boost::enable_if_c<boost::is_pointer<T>::value, bool>::type
    operator()(T pX){ return pX->getName()== mName;}

private:
    U mName;
};

对于不知道 enable_if 的人来说,这看起来很丑陋而且很难理解。 有没有更简单的方法来编写这样一个类似指针和引用的仿函数?

【问题讨论】:

    标签: c++ templates boost stl


    【解决方案1】:

    可以这么简单:

    template <class T>
    bool operator()(T const& rX) const { return rX.getName() == mName; }
    
    template <class T>
    bool operator()(T* const pX) const { return pX->getName() == mName; }
    

    【讨论】:

    • 可能指针版本与const 相同,所以我们希望T const* 作为参数。更好的是,我们可以根据参考版本来实现它:return (*this)(*pX);
    【解决方案2】:

    实现 getName 成员函数的类是否返回 std::string 以外的任何内容?如果没有,您可以去掉一个模板参数。

    这就是我实现仿函数的方式:

    class by_name
    {
      public:
        by_name(const std::string& name) :
          Name(name) {}
    
        template <class T>
        bool operator()(T const& pX) const
        {
          return pX.getName() == Name;
        }
    
        template <class T>
        bool operator()(T* pX) const
        {
          if (!pX)  // how do you handle a null ptr?
            return false;
          (*this)(*pX); // @Luc Danton 
        }
    
      private:
        std::string Name;
    };
    

    如果指针版本实现为

    bool operator(T const* pX) const {}
    

    gcc 出于某种原因选择实例化

    bool operator(T const& pX) const with [T = A*]
    

    函子已用 gcc 4.6.1 编译和测试。

    【讨论】:

    • 好主意,但我也有 QString 来处理系统中的两种字符串类型
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-30
    • 1970-01-01
    相关资源
    最近更新 更多