C++ range-for和boost :: irange

cdm*_*dmh 4 boost c++11

我正在使用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;
}
Run Code Online (Sandbox Code Playgroud)

这里有一个实时版本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))
Run Code Online (Sandbox Code Playgroud)

如果我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;
}
Run Code Online (Sandbox Code Playgroud)

这很好用: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;
}
Run Code Online (Sandbox Code Playgroud)

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

请问有什么想法吗?

seh*_*ehe 5


但是,首先,Live On Coliru出了什么问题

for (size_t i : irange(0, 100))
Run Code Online (Sandbox Code Playgroud)

甚至Live On Coliru

size_t end = 100;
for (auto i : irange(0ul, end))
Run Code Online (Sandbox Code Playgroud)

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

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

只是,你没有传递可以毫不含糊地推断出来的论点.如果你能够允许这个,那么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 << ' ';
}
Run Code Online (Sandbox Code Playgroud)