C++11 为什么';范围解析不在类之外吗?

C++11 为什么';范围解析不在类之外吗?,c++11,visual-studio-2013,iterator,reverse-iterator,C++11,Visual Studio 2013,Iterator,Reverse Iterator,我正在尝试使用std::reverse_iterator为使用双向迭代器的容器编写一个通用的反向包装器 但是,当编译器查找begin(…)或end(…)时,它会说找不到与reverse\u wrapper::begin(container)匹配的函数调用,因为候选函数需要0个参数,但提供了1个参数 我猜这是因为std::begin(myArray&)和std::end(myArray&)不存在。将它们强制放入std名称空间是行不通的(无论如何也不可取)。我还尝试从我的reverse\u包装中删除

我正在尝试使用
std::reverse_iterator
为使用双向迭代器的容器编写一个通用的反向包装器

但是,当编译器查找
begin(…)
end(…)
时,它会说找不到与
reverse\u wrapper::begin(container)
匹配的函数调用,因为候选函数需要0个参数,但提供了1个参数

我猜这是因为
std::begin(myArray&)
std::end(myArray&)
不存在。将它们强制放入
std
名称空间是行不通的(无论如何也不可取)。我还尝试从我的
reverse\u包装中删除
std::
前缀,但这不起作用,还会破坏正常的
std
容器实现

这似乎是一个范围解决问题,但我似乎无法得到解决。我做错了什么

代码:

#包括
#包括
#包括
#定义Fn1 0//std容器工程
#定义Fn2 1//非标准容器不起作用
模板
结构反向包装器
{
集装箱&集装箱;
自动开始()
->std::reverse_迭代器
{
返回std::reverse_迭代器(std::end(container));
}
自动结束()
->std::reverse_迭代器
{
返回std::reverse_迭代器(std::begin(container));
}
};
模板
自动反转(容器和容器)
->反向包装器
{
返回{container};
}
结构myArray
{
int元素[5]={1,2,3,4,5};
};
int*begin(myArray&array){return&array.elements[0];}
int*end(myArray&array){return&array.elements[5];}
#如果Fn1
无效fn1()
{
向量x={1,2,3,4,5};
用于(自动和ix:反转(x))
{

std::cout为了回应这些评论,让我写一些关于缺少自动推断返回类型的解决方法

总之,问题是您使用了一个命名空间限定的调用来调用
begin
end
,而实际上您只是使用了一个最合适的调用,而将
std::
实现用作备份

因为我在评论中提出的解决方案不起作用,你可以试试这个

在包含
reverse\u wrapper
的标题中,可以添加此方法

namespace detail {
    using std::begin;
    using std::end;
    template< typename Container >
    auto impl_begin( Container & c ) -> decltype( begin(c) ) {
         return begin(c);
    }
    // Same for end
}

template< typename Container >
class reverse_wrapper {
    Container& container;
public:
    auto end() -> decltype( detail::impl_begin(container) ) {
        return std::reverse_iterator<decltype( detail::impl_begin(container) )>( detail::impl_begin(container) );
    }
    // ... and the rest
};
名称空间详细信息{
使用std::begin;
使用std::end;
模板
自动执行开始(容器和c)->取消类型(开始(c)){
返回开始(c);
}
//结尾也一样
}
模板
类反向包装器{
集装箱&集装箱;
公众:
自动结束()->decltype(细节::impl_begin(容器)){
返回std::reverse_迭代器(detail::impl_begin(容器));
}
//…还有其他
};

作为对这些评论的回应,让我为缺少自动推断的返回类型编写一些变通方法

总之,问题是您使用了一个命名空间限定的调用来调用
begin
end
,而实际上您只是使用了一个最合适的调用,而将
std::
实现用作备份

因为我在评论中提出的解决方案不起作用,你可以试试这个

在包含
reverse\u wrapper
的标题中,可以添加此方法

namespace detail {
    using std::begin;
    using std::end;
    template< typename Container >
    auto impl_begin( Container & c ) -> decltype( begin(c) ) {
         return begin(c);
    }
    // Same for end
}

template< typename Container >
class reverse_wrapper {
    Container& container;
public:
    auto end() -> decltype( detail::impl_begin(container) ) {
        return std::reverse_iterator<decltype( detail::impl_begin(container) )>( detail::impl_begin(container) );
    }
    // ... and the rest
};
名称空间详细信息{
使用std::begin;
使用std::end;
模板
自动执行开始(容器和c)->取消类型(开始(c)){
返回开始(c);
}
//结尾也一样
}
模板
类反向包装器{
集装箱&集装箱;
公众:
自动结束()->decltype(细节::impl_begin(容器)){
返回std::reverse_迭代器(detail::impl_begin(容器));
}
//…还有其他
};

我可以想到三种可能的解决方案,其中一种已经在中介绍过;考虑到您使用的是VS 2013,我建议您使用该解决方案,但我会提供另外两种供参考

想到的第一个解决方案是,如果可能的话,将成员函数
begin()
end()
添加到
myArray
(以及它作为占位符的所有类型);最简单的方法是将函数
int*begin(myArray&)
int*end(myArray&)
进入成员函数。这允许
std::begin()
std::end()
返回适当的迭代器,从而允许
reverse\u wrapper::begin()
reverse\u wrapper::end()
工作

struct myArray
{
    int elements[5] = {1,2,3,4,5};

    int* begin() { return &elements[0]; }
    int*   end() { return &elements[5]; }
};

// int* begin(myArray& array) { return &array.elements[0]; }
// int*   end(myArray& array) { return &array.elements[5]; }
这是因为。同样地

请注意,这需要修改每个用户定义的容器类型,使其具有成员函数
begin()
end()
如果它还没有,这可能是一项耗时且容易出错的任务。如果从头开始制作容器,我建议使用这种方法,但如果使用将
begin()
end()
定义为独立函数的现有容器,则不建议使用这种方法


或者,正如注释中指出的,您可以使用using声明
using std::begin;
using std::end;
,前提是您的编译器可以执行返回类型推断

template <typename Container>
struct reverse_wrapper
{
    Container& container;

    auto begin()
//        -> std::reverse_iterator< decltype(std::end(container)) >
    {
        using std::end;
        return std::reverse_iterator< decltype(/*std::*/end(container)) >(/*std::*/end(container));
    }

    auto end()
//        -> std::reverse_iterator< decltype(std::begin(container)) >
    {
        using std::begin;
        return std::reverse_iterator< decltype(/*std::*/begin(container)) >(/*std::*/begin(container));
    }
};
模板
结构反向包装器
{
集装箱&集装箱;
自动开始()
//->std::reverse_迭代器
{
使用std::end;
返回std::reverse_迭代器(/*std::*/end(container));
}
自动结束()
//->std::reverse_迭代器
{
使用std::begin;
返回std::reverse_迭代器(/*std::*/begin(container));
}
template <typename Container>
struct reverse_wrapper
{
    Container& container;

    auto begin()
//        -> std::reverse_iterator< decltype(std::end(container)) >
    {
        using std::end;
        return std::reverse_iterator< decltype(/*std::*/end(container)) >(/*std::*/end(container));
    }

    auto end()
//        -> std::reverse_iterator< decltype(std::begin(container)) >
    {
        using std::begin;
        return std::reverse_iterator< decltype(/*std::*/begin(container)) >(/*std::*/begin(container));
    }
};