C++ 对int[2]数组进行排序不会编译

C++ 对int[2]数组进行排序不会编译,c++,sorting,std,C++,Sorting,Std,我有一个2*N整数的数据数组,表示对,即对于偶I=0,2,4,…,2*N对[I],对[I+1]就是这样的对。数据是这样格式化的,因为我使用Matlab的mex库。我有: int N=5; int数据[10]={1,2,3,4,5,6,7,8,9,10}; 结构对{int first;int second;}; 配对*配对=配对*数据; 但问题是,无法保证这一对按照第一、第二顺序排列成两个SizeFints。见: 我不想处理所有数据并将其复制到一个新的数组中,因为这是不必要的,我需要尽我所能使用它

我有一个2*N整数的数据数组,表示对,即对于偶I=0,2,4,…,2*N对[I],对[I+1]就是这样的对。数据是这样格式化的,因为我使用Matlab的mex库。我有:

int N=5; int数据[10]={1,2,3,4,5,6,7,8,9,10}; 结构对{int first;int second;}; 配对*配对=配对*数据; 但问题是,无法保证这一对按照第一、第二顺序排列成两个SizeFints。见:

我不想处理所有数据并将其复制到一个新的数组中,因为这是不必要的,我需要尽我所能使用它

typedef int对[2]; 为了确保它正确对齐,没有尾随的垃圾字节等。如果我想根据第一个元素对这些对进行排序,我可以执行以下操作:

包括 包括

我可以将错误消息总结为error:array必须使用括号内的初始值设定项进行初始化,完整消息见下文。它是由std::sort调用引起的

我把这对typedef包在一个接头里,看起来很管用。为什么C++或STD::排序不以int(2)的形式看到? 完整的编译器输出:

In file included from /usr/include/c++/4.8/bits/stl_pair.h:59:0,
                                from /usr/include/c++/4.8/bits/stl_algobase.h:64,
                                from /usr/include/c++/4.8/bits/char_traits.h:39,
                                from /usr/include/c++/4.8/ios:40,
                                from /usr/include/c++/4.8/ostream:38,
                                from /usr/include/c++/4.8/iostream:39,
                                from prog.cpp:1:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’:
/usr/include/c++/4.8/bits/stl_algo.h:2250:70:   required from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5514:55:   required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
prog.cpp:16:35:   required from here
/usr/include/c++/4.8/bits/stl_algo.h:2186:11: error: array must be initialized with a brace-enclosed initializer
    __val = _GLIBCXX_MOVE(*__i);
                    ^
In file included from /usr/include/c++/4.8/algorithm:62:0,
                                from prog.cpp:2:
/usr/include/c++/4.8/bits/stl_algo.h:2188:17: error: invalid array assignment
                *__first = _GLIBCXX_MOVE(__val);
                                ^
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, _Compare) [with _RandomAccessIterator = int (*)[2]; _Tp = int [2]; _Compare = bool (*)(int*, int*)]’:
/usr/include/c++/4.8/bits/stl_algo.h:2319:78:   required from ‘_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:2360:62:   required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = int (*)[2]; _Size = int; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5513:44:   required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
prog.cpp:16:35:   required from here
/usr/include/c++/4.8/bits/stl_algo.h:2287:35: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
        while (__comp(*__first, __pivot))
                                                                    ^
/usr/include/c++/4.8/bits/stl_algo.h:2290:34: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
        while (__comp(__pivot, *__last))
                                                                    ^
In file included from /usr/include/c++/4.8/bits/stl_pair.h:59:0,
                                from /usr/include/c++/4.8/bits/stl_algobase.h:64,
                                from /usr/include/c++/4.8/bits/char_traits.h:39,
                                from /usr/include/c++/4.8/ios:40,
                                from /usr/include/c++/4.8/ostream:38,
                                from /usr/include/c++/4.8/iostream:39,
                                from prog.cpp:1:
/usr/include/c++/4.8/bits/stl_heap.h: In instantiation of ‘void std::make_heap(_RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’:
/usr/include/c++/4.8/bits/stl_algo.h:1970:47:   required from ‘void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5363:59:   required from ‘void std::partial_sort(_RAIter, _RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:2355:68:   required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = int (*)[2]; _Size = int; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5513:44:   required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
prog.cpp:16:35:   required from here
/usr/include/c++/4.8/bits/stl_heap.h:446:25: error: array must be initialized with a brace-enclosed initializer
        _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
                                                ^
/usr/include/c++/4.8/bits/stl_heap.h: In instantiation of ‘void std::__pop_heap(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’:
/usr/include/c++/4.8/bits/stl_algo.h:1973:50:   required from ‘void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5363:59:   required from ‘void std::partial_sort(_RAIter, _RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:2355:68:   required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = int (*)[2]; _Size = int; _Compare = bool (*)(int*, int*)]’
/usr/include/c++/4.8/bits/stl_algo.h:5513:44:   required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = int (*)[2]; _Compare = bool (*)(int*, int*)]’
prog.cpp:16:35:   required from here
/usr/include/c++/4.8/bits/stl_heap.h:339:28: error: array must be initialized with a brace-enclosed initializer
            _ValueType __value = _GLIBCXX_MOVE(*__result);
                                                        ^
In file included from /usr/include/c++/4.8/bits/stl_algo.h:61:0,
                                from /usr/include/c++/4.8/algorithm:62,
                                from prog.cpp:2:
/usr/include/c++/4.8/bits/stl_heap.h:340:17: error: invalid array assignment
            *__result = _GLIBCXX_MOVE(*__first);
                                ^
您正在对数据进行排序,而不是对数据进行排序。也就是说,您的新方法仍然是未定义的行为,因此不能保证有效1。你基本上是想把一个方形的钉子装进一个圆孔里。如果您想使用std::sort,请提供有效数据–这意味着在您的案例中复制数据,或者编写一个将数组视为连续对集合的自定义迭代器


1这是一种极其轻描淡写的说法不要这样做。

将两个int的数组交换为std::pair为我带来了窍门:


赫伯特,因为它只是无效的C++。演员阵容是非法的,它违反了法律。对不起,它在哪里做到的?typedef不引入新类型;所有访问仍然是通过int类型的表达式进行的。您可以从任何类型强制转换为void*和back。@mAlter是int[2]和int[10]两种不同的类型,以便进行严格的别名处理吗?我也这么认为,虽然我承认如果不是这样的话,这是有道理的。@MSalters如果不是未定义的行为,它肯定不会按照OP的要求执行。如果sort只使用iter_交换,你可以设计一个迭代器来完成这个任务,但我认为这并不能保证。@KonradRudolph:你总是用int[1]来别名int[10]。从逻辑上讲,你应该能够使用迭代器或向量的facade模式来完成这项任务。然而,实际上,该标准似乎仍然施加了足够的限制,即使它几乎肯定会起作用,最终也会导致未定义的行为;是保证有项目的顺序,没有初始填充,IDK为什么你不这么认为。要检查是否没有填充,请测试SizeOffAir==2*SizeOffint;,这在任何理智的实现中都应该是正确的。如果不是这样,那么当你走到桥边时,你就可以穿过那座桥。@MattMcNabb,不,不是真的。据我所知,编译器通常是对齐的。例如,struct{char,int}通常会为char分配4个字节,因为在大多数机器上,RAM内存可以以模4字节的地址传输到CPU内存。因此,成员在模4地址处与我对齐,以防止需要两个RAM-CPU操作来传输一个int。当然,int通常是4字节,因此可能以合理的方式对齐两个int。尽管如此,也不能保证:@Herbert我们说的是两个int,不是char和int。我的意思是你可以做一个sizeof检查,看看你的编译器是否插入了padding,以及其他测试,来检查你的int数组是否正确对齐,如果没有对齐,那么你的代码就会工作。如果检查确实发现没有对齐,在那家分行我该怎么办?是的,这就是问题所在。std::array和std::pair不能保证以与普通int数组相同的方式对齐,因为编译器非常自由,可以根据需要对齐数据。例如,我们可以使用4个字节分配一个整数数组| 0:4b | 1:4b | | | | | | 1:9b | | | | | | 1:4b | | | | | | | | 1:9b | |。因此两者不会对齐;,虽然4byte是一个非常常见的字长,而且你的建议可能99%的时间都有效,但我不明白。在我的解决方案中,什么是未定义的行为?我只是为了两个定义良好的不同解决方案而放弃了数据阵列…而且,过了一段时间,我知道OP确实想键入擦除数据向量…问题是无法判断编译器是否在内存中正确地将std::pair和std::array与整数数组对齐。@Herbert我打赌它会经常这样做,但如果必须这样做,我会发表一个大的评论,这是一个绝望的优化D
std::sort(data, data+N, compare);
#include <iostream>
#include <algorithm>
#include <memory>

typedef std::pair<int,int> Pair;

bool compare(const Pair& i, const Pair& j) { return i.first < j.first; }

int main() {
    const int N=5;
    Pair pairs[N] = {{1,2}, {7,8}, {13,14}, {4,5}, {10,11}};

    std::cout << "unsorted" << std::endl;
    for(int i=0; i<N;++i) std::cout << i << ": (" << pairs[i].first << ", " << pairs[i].second << ")" << std::endl;

    std::sort(pairs, pairs+N, compare);

    std::cout << "sorted" << std::endl;
    for(int i=0; i<N;++i) std::cout << i << ": (" << pairs[i].first << ", " << pairs[i].second << ")" << std::endl;
}
#include <iostream>
#include <algorithm>
#include <memory>

typedef std::array<int, 2> Pair;

bool compare(const Pair& i, const Pair& j) { return i[0] < j[0]; }

int main() {
    const int N=5;
    Pair pairs[N] = {1,2, 7,8, 13,14, 4,5, 10,11};

    std::cout << "unsorted" << std::endl;
    for(int i=0; i<N;++i) std::cout << i << ": (" << pairs[i][0] << ", " << pairs[i][1] << ")" << std::endl;

    std::sort(pairs, pairs+N, compare);

    std::cout << "sorted" << std::endl;
    for(int i=0; i<N;++i) std::cout << i << ": (" << pairs[i][0] << ", " << pairs[i][1] << ")" << std::endl;
}