C++: STL-сортировка STL-вектор массива STL

Следующий код C++ и Makefile приводят к непонятной (для меня) ошибке компиляции. Может кто-нибудь объяснить

  1. В чем именно проблема?

  2. Что нужно сделать, чтобы исправить этот код? Можете привести пример?

Я успешно компилировал этот код в GCC в Cygwin, поэтому я даже не уверен, какому компилятору я могу доверять. Я прилагаю файл cpp (test.cpp), мой make-файл (использующий clang, потому что сообщение об ошибке GCC еще хуже) и фактическое сообщение об ошибке при запуске make.

test.cpp:

#include <array>
#include <vector>
#include <map>
#include <algorithm>

class Foo
{

    public:

        Foo( 
            const std::vector<std::array<int,3>> inputdata
        );

    private:

        std::vector< std::array<int,2> > membervariable;

};

Foo::Foo( 
    const std::vector<std::array<int,3>> inputdata
)
:
    membervariable( 0 )
{

    /* 1. create all edges, allocate memory */

    membervariable.resize( inputdata.size() * 3 );

    for( int t  = 0; t  < inputdata.size(); t++  )
    for( int ei = 0; ei <                        3; ei++ )
    {
      membervariable[ 0 * inputdata.size() + t ] = { inputdata[t][0], inputdata[t][1] };
      membervariable[ 1 * inputdata.size() + t ] = { inputdata[t][0], inputdata[t][2] };
      membervariable[ 2 * inputdata.size() + t ] = { inputdata[t][1], inputdata[t][2] };
    }

    std::sort( membervariable.begin(), membervariable.end() );

    auto it = std::unique( membervariable.begin(), membervariable.end() );

    membervariable.resize( it - membervariable.begin() );


}

Makefile:

CC = clang++ -O0 -g -std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -pedantic -Wall -Wextra -Wno-unused-variable -Wno-sign-compare -Wno-missing-braces -Wmissing-field-initializers -Werror=implicit
# CC =     g++ -O0 -g -std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -pedantic -Wall -Wextra -Wno-unused-variable -Wno-sign-compare -Wno-missing-braces -Wmissing-field-initializers -Werror=implicit

test.o: test.cpp
        $(CC) test.cpp -c -o test.o 

Вывод при вызове make и clang версии:

$ make
clang++ -O0 -g -std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -pedantic -Wall -Wextra -Wno-unused-variable -Wno-sign-compare -Wno-missing-braces -Wmissing-field-initializers -Werror=implicit test.cpp -c -o test.o
In file included from test.cpp:3:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/map:61:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_map.h:63:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/tuple:39:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/array:338:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/debug/array:86:52: error: too many arguments to function call, expected
      single argument '__other', have 2 arguments
      noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())))
                        ~~~~                       ^~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/debug/array:264:23: note: in instantiation of exception specification for
      'swap' requested here
    noexcept(noexcept(__one.swap(__two)))
                      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algobase.h:148:7: note: in instantiation of exception
      specification for 'swap<int, 2>' requested here
      swap(*__a, *__b);
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algo.h:84:11: note: in instantiation of function template
      specialization 'std::iter_swap<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
      std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
      std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
      __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *, std::__cxx1998::vector<std::__debug::array<int, 2>,
      std::allocator<std::__debug::array<int, 2> > > >, std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int,
      2> > > > >' requested here
            std::iter_swap(__result, __b);
                ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algo.h:1916:12: note: in instantiation of function template
      specialization 'std::__move_median_to_first<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
      std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
      std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >, __gnu_cxx::__ops::_Iter_less_iter>'
      requested here
      std::__move_median_to_first(__first, __first + 1, __mid, __last - 1,
          ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algo.h:1948:11: note: in instantiation of function template
      specialization 'std::__unguarded_partition_pivot<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
      std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
      std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >, __gnu_cxx::__ops::_Iter_less_iter>'
      requested here
            std::__unguarded_partition_pivot(__first, __last, __comp);
                ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algo.h:1963:9: note: in instantiation of function template
      specialization 'std::__introsort_loop<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
      std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
      std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >, long,
      __gnu_cxx::__ops::_Iter_less_iter>' requested here
          std::__introsort_loop(__first, __last,
              ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algo.h:4698:12: note: in instantiation of function template
      specialization 'std::__sort<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
      std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
      std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >, __gnu_cxx::__ops::_Iter_less_iter>'
      requested here
      std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
          ^
test.cpp:40:10: note: in instantiation of function template specialization
      'std::sort<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
      std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
      std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > > >' requested here
    std::sort( membervariable.begin(), membervariable.end() );
        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/debug/array:84:7: note: 'swap' declared here
      void
      ^
1 error generated.
makefile:6: recipe for target 'test.o' failed
make: *** [test.o] Error 1
$ clang++ --version
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$

1 ответ

Решение

Сообщения об ошибках, показанные в этом вопросе, касаются ошибки в стандарте ( выпуск 2456 LWG), которую стандартная библиотека GCC внедрила в букву. Компилятор GCC не диагностировал проблему с результирующим кодом (в противном случае ошибка была бы обнаружена ранее), но версия clang, которую вы использовали, делает. Позже IIRC clang добавил специальный хак, позволяющий компилировать это конкретное использование, поэтому "исправление" заключается в использовании более новой версии GCC или более новой версии Clang или обоих.

Другие вопросы по тегам