【问题标题】:My First Go With Function Templates我第一次使用函数模板
【发布时间】:2010-04-24 18:41:47
【问题描述】:

认为这很简单。

但是在运行下面的代码时,我得到一个“iterator not dereferencable”错误。

怎么了?

template<typename T>
struct SumsTo : public std::binary_function<T, T, bool>
{
    int myInt;
    SumsTo(int a)
    {
        myInt = a;
    }
    bool operator()(const T& l, const T& r)
    {   
        cout << l << " + " << r;
        if ((l + r) == myInt)
        {
            cout << " does add to " << myInt;
        }
        else 
        {
            cout << " DOES NOT add to " << myInt;
        }
        return true;
    }
};

void main()
{
    list<int> l1;
    l1.push_back(1);
    l1.push_back(2);
    l1.push_back(3);
    l1.push_back(4);

    list<int> l2;
    l2.push_back(9);
    l2.push_back(8);
    l2.push_back(7);
    l2.push_back(6);

    transform(l1.begin(), l1.end(), l2.begin(), l2.end(), SumsTo<int>(10) );
}

【问题讨论】:

    标签: c++ function templates


    【解决方案1】:

    你的函子很好。问题在于对transform 的调用。

    Transform 有原型

    transform(_InputIterator1 __first1, _InputIterator1 __last1,
              _InputIterator2 __first2, _OutputIterator __result,
              _BinaryOperation __binary_op)
    

    你的电话是

    transform(l1.begin(), l1.end(), l2.begin(), l2.end(), SumsTo<int>(10) );
    

    而不是l2.end(),第四个迭代器参数需要是结果序列的开始。它应该引用一系列可以从bool 构造的对象。

    如果你想将结果保存到l2,那么你想要

    transform(l1.begin(), l1.end(), l2.begin(), l2.begin(), SumsTo<int>(10) );
    

    正如 GMan 建议的那样,另一种方法是 std::back_inserter 来自 &lt;iterator&gt;

    vector<bool> sums10; // vector<bool> is Good Enough for Me
    transform(l1.begin(), l1.end(), l2.begin(), back_inserter(sums10), SumsTo<int>(10) );
    

    【讨论】:

    • 我想你的意思是back_inserter(sums10)。 :) 顺便说一句,不需要把我的名字放在那里。
    • 当然,我不介意。 :) 有些人只是不喜欢答案中的其他人的名字,我不关心它是否存在。不过谢谢。 :]
    【解决方案2】:

    正如 Potatoswatter 指出的,transform 有原型

    transform(_InputIterator1 __first1, _InputIterator1 __last1,
              _InputIterator2 __first2, _OutputIterator __result,
              _BinaryOperation __binary_op)
    

    这意味着前两个参数表示一个范围。在你的情况下,l1.begin(), l1.end()

    下一个参数是下一个列表的起点:l2.begin()

    第四个参数是你的麻烦所在。它要求一个“输出”迭代器,或者在某个地方放置你的操作结果。相反,您将其放在第二个列表的末尾。

    试试这个:

    //...
    list<bool> l3;
    
    transform(l1.begin(), l1.end(), l2.begin(), back_inserter(l3), SumsTo<int>(10));
    

    如果无法编译,请尝试添加#include &lt;iterator&gt;

    back_inserter 所做的是创建一个迭代器,当写入该迭代器时(这就是使其成为“输出”迭代器的原因),它会执行一个 push_back 并将其赋予传递给它的容器的值。

    【讨论】:

    • 提早#include 更好的样式以避免不确定的依赖关系...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多