【问题标题】:Overload Function call operator () for find_iffind_if 的重载函数调用运算符 ()
【发布时间】:2014-02-27 18:35:21
【问题描述】:

我有三门课

class A
class B
class C

我有两张地图

std::map<A*, B*> myMap1;
std::map<A*, C*> myMap2;

和A的对象指针

A* obj_ptr_A1 = new A;等等

我想在 A* 的两个映射上执行 find_if,所以我写了一个仿函数和重载运算符 () 两次,如下所示

class functor
{
    private:
        A* m_member;
    public:
        explicit functor(A* input) : m_member(input){}

        bool operator()(const std::pair<A*, B*>& iter) const
        {
             return (m_member->GetValue() == (iter.first)->GetValue());
        }

        bool operator()(const std::pair<A*, C*>& iter) const
        {
             return (m_member->GetValue() == (iter.first)->GetValue());
        }
};

其中 GetValue() 是 A 的成员函数,返回一个整数。 用法:

if(std::find_if(myMap1.begin(), myMap1.end(), functor(obj_ptr_A1)) != myMap1.end())
{
    std::cout << "Found in myMap1" << std::endl;
}


if(std::find_if(myMap2.begin(), myMap2.end(), functor(obj_ptr_A1)) != myMap2.end())
{
    std::cout << "Found in myMap2" << std::endl;
}

这给了我编译错误 error C3066: there are multiple ways that an object of this type can be called with these arguments 这是重载错误吗?

完整代码在这里http://pastebin.com/DnUQKHPp 它给出了编译错误。

【问题讨论】:

  • 试试std::pair&lt;A* const, B*&gt; const&amp; 等。你也可以使用函数模板,因为函数看起来相同/相似:template&lt;class T&gt; bool operator()(T const&amp;) const { ... }
  • 嗯,你能提供一个SSCCE吗?
  • operator() 的重载在 pastebin 中与您的问题中不同:/
  • 好吧,it works
  • 这工作正常ideone.com/yMgOaO

标签: c++ class operator-overloading


【解决方案1】:

尝试以下(未经测试)

template <class T>

class functor
{
    private:
        A* m_member;
    public:
        explicit functor(A* input) : m_member(input){}

        bool operator()(const std::pair<A*, T*>& iter) const
        {
             return (m_member->GetValue() == (iter.first)->GetValue());
        }
};

if(std::find_if(myMap1.begin(), myMap1.end(), functor<B>(obj_ptr_A1)) != myMap1.end())
{
    std::cout << "Found in myMap1" << std::endl;
}


if(std::find_if(myMap2.begin(), myMap2.end(), functor<C>(obj_ptr_A1)) != myMap2.end())
{
    std::cout << "Found in myMap2" << std::endl;
}

【讨论】:

  • 这并不能解决我在 OP 的帖子中看到的问题,并且有更简洁的方法来编写它。你的答案通常都很好,你累了吗?
【解决方案2】:

我发现,如果您将Argument 设为模板参数而不是A*,则可以在映射中进行不同的键值组合,前提是您将functor::operator() 设为Iterator 的模板.

这是仿函数的样子:

template<typename Argument> 
class functor
{
private:
    Argument m_member;
public:

    functor(Argument a)
        : 
            m_member(a)
    {}

    template<typename PairIterator>
    bool operator()(PairIterator iter) const
    {
        return (m_member->GetValue() == (iter.first)->GetValue());
    }
};

这是函子生成器:

template<typename Argument>
functor<Argument> make_functor(Argument const & a)
{
    return functor<Argument>(a); 
}

here 是完整的在线示例。

【讨论】:

  • @MooingDuck:也许吧。我喜欢它,因为它摆脱了重载并适用于不同的组合,这就是我发布它的原因......也许有人觉得这很有用。
  • 我不清楚。这个答案很好advice(ergo,没有downvote),它似乎并没有回答为什么他的代码根本不起作用。这个答案只是用更好的工作代码替换了损坏的代码,没有解释什么是损坏的。
  • @MooingDuck:一切都清楚。我应该删除答案还是解决错误?
  • 如果您在顶部插入一句话说明他的代码有什么问题,然后说“但是,模板会大大增强您的functor,如下所示...”,我会更高兴
  • 酷。会的,但明天早上第一件事,我累死了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 2011-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多