C ++ range-for和boost :: irange

时间:2015-04-30 11:12:26

标签: c++11 boost

我使用boost::irange创建了一个辅助函数,通过消除对显式模板参数的需求来简化代码。我不明白为什么它不起作用。这是代码:

#include <iostream>
#include <boost/range/irange.hpp>

template<typename T>
boost::irange<T> range_from_zero(T limit)
{
    return boost::irange<T>(T(), limit);
}

int main() {
    size_t end = 100;
    for (auto i  : range_from_zero(0,end))
        std::cout << i << ' ';

    return 0;
}

这里有一个实时版本https://ideone.com/VVvW6e,会产生编译错误

prog.cpp:5:8: error: 'irange<T>' in namespace 'boost' does not name a type
 boost::irange<T> range_from_zero(T limit)
        ^
prog.cpp: In function 'int main()':
prog.cpp:12:41: error: 'range_from_zero' was not declared in this scope
     for (auto i  : range_from_zero(0,end))

如果我直接在范围中使用boost::irange,那么它可以工作:

#include <iostream>
#include <boost/range/irange.hpp>

int main() {
    size_t end = 100;
    for (auto i  : boost::irange<size_t>(0,end))
        std::cout << i << ' ';

    return 0;
}

这很好用:https://ideone.com/TOWY6H

我认为在函数返回时使用range-for可能是一个问题,但它不是;这可以使用std::vector

#include <iostream>
#include <boost/range/irange.hpp>

template<typename T>
std::vector<T> range_from_zero(T limit)
{
    auto range = boost::irange<T>(T(), limit);
    return { std::begin(range), std::end(range) };
}

int main() {
    size_t end = 100;
    for (auto i : range_from_zero(end))
        std::cout << i << ' ';

    return 0;
}

请参阅https://ideone.com/TYRXnC

请问任何想法?

1 个答案:

答案 0 :(得分:5)

但是,首先, Live On Coliru

的错误是什么?
for (size_t i : irange(0, 100))

甚至 Live On Coliru

size_t end = 100;
for (auto i : irange(0ul, end))

irange是一个函数模板,不能用作返回类型。

返回类型为integer_rangestrided_integer_range。因此,irange已经是您正在寻找的功能。

只是,你没有传递可以明确推断的参数。如果你能允许这样做,&#34;复制&#34; irange()实现使用单独的模板参数类型作为边界值并使用例如std::common_type<T1,T2>::type作为范围元素。

这是我在编写range_from_zero时没有在界面中命名实现细节的尝试:

<强> Live On Coliru

#include <iostream>
#include <boost/range/irange.hpp>

template <typename T>
auto izrange(T upper) -> decltype(boost::irange(static_cast<T>(0), upper)) {
    return boost::irange(static_cast<T>(0), upper);
}

int main() {
    size_t end = 100;
    for (size_t i : izrange(end))
        std::cout << i << ' ';
}