相关疑难解决方法(0)

C++ 11:使用容器参数定义函数(如基于范围)?

在C++ 11中经常需要定义一个以容器作为参数的函数.

例如,让我们定义一个函数addup(是的只是一个简单的版本std::accumulate):

template <class I>
int addup (I first, I last)
{
    int x = 0;
    while ( first != last )
        x += *first++;
    return x;
}
Run Code Online (Sandbox Code Playgroud)

这需要一个迭代器范围,这是灵活的标准库惯用法.

但是假设我有一个功能:

vector<T> f();
Run Code Online (Sandbox Code Playgroud)

我必须这样做:

auto v = f();
int x = addup(v.begin(), v.end());
Run Code Online (Sandbox Code Playgroud)

我宁愿这样做:

int x = addup(f());
Run Code Online (Sandbox Code Playgroud)

就像我可以这样做:

for (auto t : f())
    ...
Run Code Online (Sandbox Code Playgroud)

本着基于范围的精神,我想要这样的事情:

template<class C>
int addup(C&& container)
{
    addup(beginexpr(container), endexpr(container)); // ???
}
Run Code Online (Sandbox Code Playgroud)

在标准中它在6.5.4(释义)中说:

(A)if container是数组类型,beginexpr并且endexpr …

c++ c++11

13
推荐指数
1
解决办法
1479
查看次数

将using语句应用于函数的返回类型,而不应用于整个命名空间

我正在尝试创建一个接受底层容器的函数,并根据对元素进行一些处理的自定义迭代器返回一个boost :: iterator_range.

例如

// The range class, templated on the underlying iterator type
template<class Iter> using CustomRange = boost::iterator_range<CustomIterator<Iter>>;

using std::begin;
template <class Container>
auto make_custom_range(Container& c) -> CustomRange<decltype(begin(c))> {
    using std::end;
    return make_custom_range_from_iterators(begin(c),end(c));
}
Run Code Online (Sandbox Code Playgroud)

代码有效(给定CustomIterator和make_custom_range_from_iterators的合适定义).

我担心的是 using std::begin声明,我认为这将导致std :: begin被导入到声明我的函数的整个命名空间.我不喜欢在decltype中明确使用std :: begin,这样ADL就可以工作了(就像这个问题:依赖于ADL for std :: begin()和std :: end()?).

我想在C++ 14中,我可以在这里使用自动返回类型.有C++ 11解决方案吗?有没有办法让返回类型看到using声明而不将它暴露给整个命名空间?

c++ argument-dependent-lookup c++11

12
推荐指数
1
解决办法
305
查看次数

如何为您自己的类型提供免费的开始/结束功能

在他最近的一次演讲中,Herb Sutter建议更喜欢免费的begin(container) end(container)功能模板container.begin().我喜欢它,因为可以为所有不带有begin()/ end()方法的可迭代类型提供这些函数.由于我的大多数域类都具有以域语言进行通信的接口,并且不使用诸如begin/end之类的通用名称,因此我现在可以提供与STL容器兼容的可迭代接口和用于循环的范围,而不会弄乱主类接口.我想知道为我自己的类型提供开始/结束函数的最佳方法是什么.我的第一个想法是以与我一样的方式执行它,swap并在我的类型所在的同一命名空间中编写函数.

namespace My
{

class Book
{
public:
    typedef std::vector<Page>::const_iterator PageIterator;

    PageIterator FirstPage() const { return begin(pages_); }
    PageIterator LastPage() const { return end(pages_); }

private:
    std::vector<Page> pages_;
};

Book::PageIterator begin(const Book& b)
{
    return b.FirstPage();
}

Book::PageIterator end(const Book& b)
{
    return b.LastPage();
}

}
Run Code Online (Sandbox Code Playgroud)

可以在这里依赖ADL,还是应该在std命名空间中?我认为另一种方法是在std命名空间中提供特化(不允许在std中重载,对吧?).特别是关于基于范围的循环查找的最佳方法是什么?

c++ c++11

9
推荐指数
2
解决办法
821
查看次数

标签 统计

c++ ×3

c++11 ×3

argument-dependent-lookup ×1