标签: stl-algorithm

std :: back_inserter需要旧GCC上的const_reference.为什么?

我目前正在查看一些代码,这些代码可以在较新版本的GCC上编译,但不能在较旧版本的GCC上编译.在我来说,我使用的是std::back_inserterstd::copy从一个数据结构中的一些数据,自定义数据结构.typedef value_type & const_reference但是,如果我忘记了此自定义数据结构中的typedef,则无法在GCC 4.4上编译.相同的代码在GCC 4.5上编译并运行正常.

这两个编译器版本之间有什么区别,这使得代码在一个版本上编译而在另一个版本上编译.我猜它与C++ 11的实现有关,这在GCC 4.4中完全不那么完整.decltype我想可能是某个或者另一个新的C++ 11关键字.

这个代码也正确,如果我使用std::back_inserter没有定义const_reference类型?我通常认为,一个必须实现全套的typedef(的value_type,reference,const_reference等),以便为与STL-算法库兼容?或者我可以安全地假设,如果我的代码在这种情况下编译,我不会调用任何危险的东西(例如移动语义,这会破坏我的其他数据结构).

c++ stl stl-algorithm

5
推荐指数
1
解决办法
862
查看次数

如何通过元素出现次数将多集合排序到容器

我想得到按其出现次数排序的元素.这就是我想出的(mHeights是一个std :: multiset):

namespace{
  template<class U,class T>
  class HistPair{
    public:
      HistPair(U count,T const& el):mEl(el),mNumber(count){      
      }
      T const&  getElement()const{return mEl;}

      U getCount()const{return mNumber;}
    private:
      T mEl;
      U mNumber;
  };

  template<class U,class T>
  bool operator <(HistPair<U,T> const& left,HistPair<U,T> const& right){
    return left.getCount()< right.getCount();
  }
}

std::vector<HistPair<int,double>  > calcFrequentHeights(){
  typedef HistPair<int,double> HeightEl;
  typedef std::vector<HistPair<int,double>  > Histogram;
  std::set<double> unique(mHeights.begin(),mHeights.end());
  Histogram res;
  boostForeach(double el, unique) {
    res.push_back(HeightEl(el,mHeights.count(el)));    
  }
  std::sort(res.begin(),res.end());
  std::reverse(res.begin(),res.end()); 
  return res;
}
Run Code Online (Sandbox Code Playgroud)

所以首先我从multiset中获取所有独特元素,然后我计算它们并将它们分类到一个新容器中(我需要计数,所以我使用了一个映射).对于这么简单的任务来说,这看起来很复杂.除了在其他地方使用的HistPair之外,没有任何stl算法可以简化此任务,例如使用equal_range或sth.一样.

编辑:我也需要出现次数,对不起,我忘记了

c++ sorting stl stl-algorithm

5
推荐指数
1
解决办法
2872
查看次数

如何对std :: shared_ptr <Widget>对象的容器进行排序?

class Widget;

std::vector< std::shared_ptr<Widget> > container

class Criterium
{
public:
    bool operator()(const Widget& left, const Widget& right)const;
};
Run Code Online (Sandbox Code Playgroud)

如何根据Criterium对容器进行排序,而不是定义另一个标准,如:

class CriteriumForPointers
{
public:
    bool operator()(const std::shared_ptr<Widget>& left, 
                    const std::shared_ptr<Widget>& right)const;
};
Run Code Online (Sandbox Code Playgroud)

c++ stl-algorithm c++11

5
推荐指数
1
解决办法
4255
查看次数

需要:用于维护一维范围列表的C++类

我正在寻找一个可以维护一维范围列表的C++类.

每个范围都定义为一(start,len)对.

我希望能够向列表中添加其他扩展区并自动合并它们.也就是说,如果我们拥有(0,5)(10,5)在列表中,并(5,5)加入,新的列表应该只包含(0,15).

永远不会从列表中删除范围.

有这样的事吗?

谢谢.

c++ algorithm stl-algorithm

5
推荐指数
1
解决办法
142
查看次数

使用back_inserter复制算法

我不明白为什么这段代码是准确的

vector<int> coll;
coll.reserve(2*coll.size());
copy (
  coll.begin(), coll.end(),    // zrodlo
  back_inserter(coll)          // przeznaczenie
);
Run Code Online (Sandbox Code Playgroud)

coll.end()代表矢量的结束.在我推回任何东西(如同back_insert_iterator)后,coll.end()返回的内容与之前的内容相同或不同之处?是否有多个终止迭代器?为什么end()可以用作容器的末尾,即使添加了新内容?

此外,您无法将代码应用于列表容器 - 它会卡住.这很重要,因为在向量的情况下,push_back使得迭代器在重新分配数据(何时size()==capacity()push_back()被调用)后不可靠,而在列表的情况下则不是这样.为什么代码挂起列表?

编辑:(sscce)

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

template <class T>
inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="")
{
    typename T::const_iterator pos;

    std::cout << optcstr;
    for (pos=coll.begin(); pos!=coll.end(); ++pos) {
        std::cout << *pos << ' ';
    }
    std::cout << std::endl;
}

int main(){
  list<int> coll;

  list<int>::iterator end = coll.end(); …
Run Code Online (Sandbox Code Playgroud)

c++ stl-algorithm

5
推荐指数
2
解决办法
2029
查看次数

SIMD实现std :: nth_element

我有一个算法,运行在我的双核,3 GHz英特尔处理器平均250毫秒,我正在尝试优化它.目前,我有一个std::nth_element呼叫,std::vector在150到300个元素之间调用大约6000次,平均需要50ms.我花了一些时间来优化我使用的比较器,它目前double从向量中查找两个并执行简单的<比较.比较器运行的时间可以忽略不计std::nth_element.比较器的拷贝构造函数也很简单.

由于此调用当前占用了我的算法的20%的时间,并且由于时间大部分花费在nth_element我没写的代码上(即不是比较器),我想知道是否有人知道优化的方法nth_element使用SIMD或任何其他方法?我已经看到了一些关于std::nth_element使用OpenCL和多线程进行并行化的问题,但由于这些向量很短,我不确定从这种方法中获得多少好处,尽管我很容易被告知我错了.

如果有SSE方法,我可以使用任何SSE指令(当前,我认为)SSE4.2.

谢谢!

c++ performance sse simd stl-algorithm

5
推荐指数
1
解决办法
746
查看次数

是否可以将std :: sort与带有额外参数的sort函数一起使用?

这是我一直在考虑的事情.我已经做了一些研究而且找不到任何东西,但我也没有发现任何相反的东西.

考虑一下这个std::sort功能<algorithm>.它需要两个迭代器和一个函数指针作为参数.所以,如果我想按字母顺序对字符串向量进行排序,我会这样做:

bool ascending(std::string lhs, std::string rhs) { return lhs < rhs; }

std::sort(my_vector.begin(), my_vector.end(), ascending);
Run Code Online (Sandbox Code Playgroud)

问题是这种类型的排序函数区分大小写,因此在以大写"Z"开头的字符串后面会放置以小写"a"开头的字符串.我看到的唯一可见的解决方案是创建一个额外的功能bool ascending_case_insensitive().但是,如果我可以在sort中使用bool ascending()带有附加bool is_case_sensitive参数的函数,那就太好了.这可能吗?

c++ sorting algorithm stl-algorithm c++11

5
推荐指数
2
解决办法
6638
查看次数

将C++成员函数指针传递给STL算法

我有一个成员函数如下:

class XYZ{
public:
    float function(float x);
private:
    float m_DensityMin;
    float m_DensityMax;
};
Run Code Online (Sandbox Code Playgroud)

现在,我试图通过传递成员函数并将结果值存储在向量中std::vector<float> foo来使用std::transformSTL算法转换a .functionbar

如果我将函数用作全局函数,使用应该表示类的成员变量的随机数据,它可以正常工作.

但是,由于函数需要使用成员变量m_DensityMinm_DensityMax类,我需要将它用作成员函数.这就是我尝试过的:

std::transform(foo.begin(), foo.end(), bar.begin(), &XYZ::function);
Run Code Online (Sandbox Code Playgroud)

但我最终得到VS2010中的错误:

error C2065: term does not evaluate to a function taking 1 arguments
Run Code Online (Sandbox Code Playgroud)

据我所知,我只传了一个论点.有什么指针吗?这是一个类似的问题,我尝试过使用std :: mem_fun,因为std :: mem_fn对我来说无法使用,但无济于事.

c++ stl member-functions stl-algorithm

5
推荐指数
1
解决办法
2642
查看次数

在并行算法中使用range :: view :: iota

由于在没有基于索引的算法并行,我想知道是否可以结合使用来模拟。那是:ranges::view::iotastd::for_each

using namespace std;

constexpr int N= 10'000'000;
ranges::iota_view indices(0,N);
vector<int> v(N);

for_each(execution::par_unseq,indices.begin(),indices.end(),[&](int i) { v[i]= i; });
Run Code Online (Sandbox Code Playgroud)

iota_view似乎提供了对适当类型的随机访问([range.iota.iterator]):

iota_view<I, Bound>::iterator::iterator_category 定义如下:

(1.1) -如果I模型Advanceable,然后iterator_categoryrandom_access_iterator_tag

(1.2) -否则,如果I模型Decrementable,然后iterator_categorybidirectional_iterator_tag

(1.3) -否则,如果I模型Incrementable,然后iterator_categoryforward_iterator_tag

(1.4)-否则iterator_categoryinput_iterator_tag

上面的代码正确吗?使用iota_view这种方式是否会降低性能?


编辑:我已经使用range-v3cmcstl2和Intel的PSTL进行了一些测试。

使用range-v3,以上示例无法使用GCC …

c++ stl-algorithm range-v3 c++17 c++20

5
推荐指数
1
解决办法
1964
查看次数

STL算法和back_inserter可以预分配空间吗?

如果我有类似的东西:

vector<int> longVector = { ... };
vector<int> newVector;
transform(longVector.begin(), longVector.end(), back_inserter(newVector),
          [] (int i) { return i * i; });
Run Code Online (Sandbox Code Playgroud)

STL是否能够newVector在处理和添加新元素之前预先分配空间?我知道这不是算法的要求,但是"好的"实现能够优化吗?或者,对于这种情况,我newVector.reserve(longVector.size());之前应该更喜欢添加吗?我不一定要问每个stdlib实现是否存在(尽管如果有人知道特定的例子会很好),但考虑到算法的接口和要求,更多是否可能(和预期).

这个问题适用于多个STL算法transform,copy,move,fill_n,...而且不只是back_inserter,也front_inserterinserter我想.

编辑:为了清楚起见,我的意思是一个STDLIB是否能够提供的具体实现中,例如,transform,对于情况下,当输出迭代是back_insertervector,在这种情况下,将访问向量的对象并保留足够的空间来存储该distance在实际运行转换之前,在给定的迭代器对之间.

c++ memory stl stdvector stl-algorithm

5
推荐指数
1
解决办法
344
查看次数