C++标准库的max_element算法需要将迭代器作为模型的输入传递ForwardIterator.
我的理解是通过指定您可以使用a 多次迭代相同的范围来ForwardIterator提炼.因此,多遍算法需要s.InputIteratorForwardIteratorForwardIterator
但是,max_element不是多遍算法 - 只需迭代一次范围就可以确定其最大元素.那么为什么max_element需要额外的功能ForwardIterator呢?
受这个问题的启发,询问如何将一个向量附加到自身,我的第一个想法是以下(是的,我意识到insert现在是一个更好的选择):
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main() {
std::vector<int> vec {1, 2, 3};
std::copy (std::begin (vec), std::end (vec), std::back_inserter (vec));
for (const auto &v : vec)
std::cout << v << ' ';
}
Run Code Online (Sandbox Code Playgroud)
但是,这打印:
1 2 3 1 * 3
Run Code Online (Sandbox Code Playgroud)
每次运行程序时*都是不同的数字.只有2被替换的事实是特殊的,如果真的有解释,我会有兴趣听到它.继续,如果我附加到不同的向量(原始副本),它会正确输出.如果我在前一行之前添加以下行,它也会正确输出copy:
vec.reserve (2 * vec.size());
Run Code Online (Sandbox Code Playgroud)
std::back_inserter尽管事先没有预留内存,但我认为这是一种将元素添加到容器末端的安全方法.如果我的理解是正确的,复制线有什么问题?
我假设它与编译器无关,但我使用的是GCC 4.7.1.
我使用的vector::emplace_back是为了避免在填充矢量时构造时间对象.这里有一个简化版本:
class Foo {
public:
Foo(int i, double d) : i_(i), d_(d) {}
/* ... */
};
std::vector<Foo> v;
v.reserve(10);
for (int i = 0; i < 10; i++)
v.emplace_back(1, 1.0);
Run Code Online (Sandbox Code Playgroud)
但我想std::fill_n改用:
v.reserve(10);
std::fill_n(std::back_inserter(v), 10, Foo(1, 1.0));
Run Code Online (Sandbox Code Playgroud)
通过这种方式,将创建临时副本.我不知道emplace在这种情况下如何使用.我想我需要类似的东西std::back_emplacer,但我找不到这样的东西.这是C++ 11的一部分,但还没有在GCC中实现?如果它不是C++ 11的一部分,还有其他方法吗?
我不太了解std::is_sorted算法及其默认行为.如果我们查看cppreference,它会说默认情况下std::is_sorted使用<运算符.而不是那样,我发现使用<=是自然的.但我的问题是,对于以下数字列表:
1 2 3 3 4 5
Run Code Online (Sandbox Code Playgroud)
它会回来true,即使3 < 3应该false.怎么可能?
编辑:它似乎比我想象的更糟糕,因为std::less_equal<int>在这种情况下传递将返回false ...当我传递比较器函数时应用的条件是什么?
想象一下,我们有以下情况:
struct A
{
int i;
};
struct B
{
A a;
int other_things;
};
bool predicate( const A& a)
{
return a.i > 123;
}
bool predicate( const B& b)
{
return predicate(b.a);
}
int main()
{
std::vector< A > a_source;
std::vector< B > b_source;
std::vector< A > a_target;
std::vector< B > b_target;
std::copy_if(a_source.begin(), a_source.end(), std::back_inserter( a_target ), predicate);
std::copy_if(b_source.begin(), b_source.end(), std::back_inserter( b_target ), predicate);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这两个调用都会std::copy_if产生编译错误,因为predicate()编译器不能接受函数的正确重载,因为std::copy_if模板签名接受任何类型的谓词:
template<typename _IIter,
typename _OIter, …Run Code Online (Sandbox Code Playgroud) 给定二维数组
std::array<std::array<int, 2>, 3> m = {{ {1, 2}, {3, 4}, {5, 6} }};
Run Code Online (Sandbox Code Playgroud)
我正在寻找所有元素的总和 - 在这种情况下,21.如果数组是一维的,我可以写
auto sum = std::accumulate(m.begin(), m.end(), 0);
Run Code Online (Sandbox Code Playgroud)
但对于我的二维数组,这失败了,这是一个可以理解的错误
no match for 'operator+' (operand types are 'int' and 'std::array<int, 2ul>')
Run Code Online (Sandbox Code Playgroud)
我怎样才能优雅地为我的2D数组计算这个总和(避免for循环,更喜欢STL算法)?
是否可以像一维情况一样使用单线,或者它变得更复杂?
我试图在一个简单的特定问题上理解面向数据的设计.如果我正在做一些非常愚蠢的事情,请提前向面向数据的设计人员道歉,但我很难理解为什么以及我的推理失败的原因.
假设我有一个简单的操作,即,float_t result = int_t(lhs) / int_t(rhs).如果我将所有变量保存在相应的容器中,例如,std::vector<float_t>和std::vector<int_t>,并且我使用std::transform,我得到正确的结果.然后,对于一个具体的例子,其中using float_t = float与using int_t = int16_t我假定包装内的这些变量struct,在一个64位架构,并加以收集在容器内应该产生更好的性能.
我认为struct组成一个64位对象,并且单个内存访问struct将给我所需的所有变量.另一方面,当所有这些变量都收集在不同的容器中时,我将需要三种不同的内存访问来获取所需的信息.以下是我设置环境的方法:
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <iostream>
#include <vector>
using namespace std::chrono;
template <class float_t, class int_t> struct Packed {
float_t sinvl;
int_t s, l;
Packed() = default;
Packed(float_t sinvl, int_t s, int_t l) : sinvl{sinvl}, s{s}, l{l} {}
void comp() …Run Code Online (Sandbox Code Playgroud) 由于for_each接受的函数只接受一个参数(向量的元素),我必须定义一个static int sum = 0 某处,以便在调用for_each后可以访问它.我觉得这很尴尬.有没有更好的方法(仍然使用for_each)?
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
static int sum = 0;
void add_f(int i )
{
sum += i * i;
}
void test_using_for_each()
{
int arr[] = {1,2,3,4};
vector<int> a (arr ,arr + sizeof(arr)/sizeof(arr[0]));
for_each( a.begin(),a.end(), add_f);
cout << "sum of the square of the element is " << sum << endl;
}
Run Code Online (Sandbox Code Playgroud)
在Ruby中,我们可以这样做:
sum = 0
[1,2,3,4].each { |i| sum += i*i} #local variable can be …Run Code Online (Sandbox Code Playgroud) 有没有办法使用std :: ostream_iterator(或类似的),以便不为最后一个元素放置分隔符?
#include <iterator>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int main(int argc, char *argv[]) {
std::vector<int> ints = {10,20,30,40,50,60,70,80,90};
std::copy(ints.begin(),ints.end(),std::ostream_iterator<int>(std::cout, ","));
}
Run Code Online (Sandbox Code Playgroud)
会打印
10,20,30,40,50,60,70,80,90,
我试图避免落后的分隔符.我想要打印
10,20,30,40,50,60,70,80,90
当然,你可以使用一个循环:
for(auto it = ints.begin(); it != ints.end(); it++){
std::cout << *it;
if((it + 1) != ints.end()){
std::cout << ",";
}
}
Run Code Online (Sandbox Code Playgroud)
但是考虑到基于C++ 11范围的循环,跟踪位置是很麻烦的.
int count = ints.size();
for(const auto& i : ints){
std::cout << i;
if(--count != 0){
std::cout << ",";
}
}
Run Code Online (Sandbox Code Playgroud)
我愿意使用Boost.我查看了boost :: algorithm :: …
我正在查看std::find_ifcppreference.com上的各种签名,我注意到采用谓词函数的风格似乎是按值接受它:
template< class InputIt, class UnaryPredicate >
InputIt find_if( InputIt first, InputIt last,
UnaryPredicate p );
Run Code Online (Sandbox Code Playgroud)
如果我正确理解它们,带有捕获变量的lambdas会为其数据的引用或副本分配存储空间,因此可能会出现"按值传递"意味着会为调用复制捕获数据的副本.
另一方面,对于函数指针和其他直接可寻址的东西,如果直接传递函数指针,而不是通过引用指针(指向指针),性能应该更好.
首先,这是正确的吗?UnaryPredicate以上是否是一个按值参数?
第二,我对传递lambdas的理解是否正确?
第三,在这种情况下,是否有理由通过价值而非参照?更重要的是,是不是有一些足够模糊的语法(hello,通用引用)可以让编译器做任何想要获得最大性能的东西?