【问题标题】:begin, end specifications for iterators for simple class简单类的迭代器的开始、结束规范
【发布时间】:2015-01-04 15:31:12
【问题描述】:

我想在我的 Foo 类上使用我的 printContainer()。
我的 printContainer 在基本的 stl::vectors 上运行良好,如 main() 所示。 我的 Foo 类的 begin() end() 成员函数似乎在 main() 的循环范围内工作。
但是我不能在我的 Foo 类上调用我的 printContainer() 。错误是错误:没有匹配的函数调用'begin(
我做错了什么?

#include <vector>
#include <iostream> 

template <typename Iter, typename Cont>
bool isLast(Iter iter, const Cont& cont) {
    return (iter != cont.end()) && (next(iter) == cont.end());
}

template <typename T>
struct is_cont {
    static const bool value = false;
};
template <typename T,typename Alloc>
struct is_cont<std::vector<T,Alloc> > {
    static const bool value = true;
};

template <typename T, typename std::enable_if< !is_cont<typename T::value_type>::value>::type* = nullptr >
std::string printContainer(T const& container)
{
    std::string str = "{";
    for (auto it = std::begin(container); it != std::end(container); ++ it)
        str += (isLast(it, container) ? std::to_string(*it) + "}" : str += std::to_string(*it) + ",");
    return str;
}

template <typename T, typename std::enable_if< is_cont<typename T::value_type>::value>::type* = nullptr >
std::string printContainer(T const& container)
{
    std::string str = "{"; 
    for (auto it = std::begin(container); it != std::end(container); ++ it)
        str += (isLast(it, container) ? printContainer(*it) + "}" : str += printContainer(*it) + ",");
    return str;
}

template <class T, class cmp=std::greater<T>>
class Foo
{
private:
    std::vector<T> data_;
public:
    typedef typename std::vector<T>::value_type  value_type;

    Foo(size_t n, T val) : data_(n, val) {}
    typename std::vector<T>::iterator begin(){ return data_.begin(); } // for printContainer
    typename std::vector<T>::iterator end()  { return data_.end();   }   // for printContainer
};

int main()
{
    std::vector<std::vector<float>> a(2,std::vector<float>(3,3));
    std::cout << printContainer(a) << std::endl; // it works !

    Foo<float> b(10,2);
    for (auto it = std::begin(b); it != std::end(b); it ++)
        std::cout << *it << " ";  // it works !

    // std::cout << printContainer(b) << std::endl;  // but this does not work !
}

【问题讨论】:

    标签: c++ templates c++11 iterator


    【解决方案1】:

    您传递了一个const 容器,因此您需要Foo::begin() constFoo::end() const 成员函数。

    您必须在 Foo 类中添加那些 const 成员,然后返回 const 迭代器:

    typename std::vector<T>::const_iterator begin() const { return data_.cbegin(); } // for printContainer
    typename std::vector<T>::const_iterator end() const { return data_.cend();   }   // for printContainer
    

    Live Demo

    【讨论】:

    • 哦,谢谢……我傻了……但是……怎么会有这么多用 printContainer(b) 打印的元素?应该只有 10 个。
    • @coincoin :那是另一个问题。调用的 printcontainer 是奇怪的递归,而不是另一个。您可能需要重新考虑实际的实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    相关资源
    最近更新 更多