C++の機能(テンプレートなど)の学習・練習目的で以下のようにマージソートを書いたら, 大量のエラー(およそ10000文字)を吐かれました。
しかし、エラーを読んでも自分の書いたソースの部分が無く、原因がわかりません。
出来る範囲でいろいろ試してみたところ、
l.24 std::vector<decltype(*first)> v((size_t)dist);
の部分に問題があることがわかり、
このdecltype(*first)
を例えばint
やlong
等にすると動きました(ソートもきちんとされていました)。しかし、例えば
C++
1if(typeid(decltype(*first)) == typeid(int)) cout<<"It's same!"<<endl;
のようなコードを書いて検証すると、条件式は真と評価されるので、やはり*first
の型は(以下のコードの場合)int
型で合っているように思えます。
一体何が原因なのか思い当たりません。どなたかご教示ください。
該当のソースコード
C++
1#include <iostream> 2#include <vector> 3#include <algorithm> 4#include <random> 5 6using Distance = long long; 7 8template<class ContainerItr> 9void MergeSort(const ContainerItr first, const ContainerItr last){ 10 if(first+1==last)return; 11 12 const ContainerItr mid = first + std::distance(first,last)/2; 13 ContainerItr itrFormer = first, itrLatter = mid; 14 15 const Distance dist = std::distance(first,last); 16 Distance distFormer = std::distance(first,mid); 17 Distance distLatter = std::distance(mid,last); 18 19 MergeSort(first,mid); 20 MergeSort(mid,last); 21 22 // 問題の起きた箇所 23 std::vector<decltype(*first)> v((size_t)dist); 24 25 // 例えばContainerItrがstd::vector<int>::iteratorのとき,この問題の箇所を次の行のようにすれば動く 26 // std::vector<int> v((size_t)dist); 27 28 for(int i=0;i<dist;++i) { 29 if (distFormer && distLatter) 30 v[i] = *(*itrFormer <= *itrLatter ? (distFormer--, itrFormer++) : (distLatter--, itrLatter++)); 31 else v[i] = *(distFormer ? (distFormer--, itrFormer++) : (distLatter--, itrLatter++)); 32 } 33 // マージした結果を元のコンテナに戻す 34 for(auto itr=first;itr!=last;++itr)*itr = v[std::distance(first,itr)]; 35} 36 37// vectorの要素を1行に並べて標準出力 38template<class PrintableIterator> 39void PrintVec(PrintableIterator first, PrintableIterator last){ 40 std::cout<<*first; 41 for(auto itr=first+1;itr!=last;++itr)std::cout<<" "<<*itr; 42 std::cout<<std::endl; 43} 44 45using namespace std; 46 47#define NUM (1<<6) 48int main(){ 49 random_device seed_gen; 50 mt19937_64 engine(seed_gen()); 51 uniform_int_distribution<> distr(1,NUM); 52 vector<int> vm(NUM); 53 54 // vm[i]を1~NUMの範囲の乱数で初期化 55 for(int i=0;i<NUM;++i)vm[i]=distr(engine); 56 cout<<"\nvm initialized\n"; 57 58 if(NUM<100)PrintVec(vm.begin(),vm.end()); 59 MergeSort(vm.begin(),vm.end()); 60 if(NUM<100)PrintVec(vm.begin(),vm.end()); 61 62 // ソートされたかどうかチェック 63 cout<<(is_sorted(vm.begin(),vm.end())?"":"not ")<<"sorted: "<<NUM<<endl; 64 65 return 0; 66}
エラーメッセージ
※あまりに長く文字数制限を優に超えてしまうので、主観でどうでも良さそうなところを削りました
※セキュリティ上の理由により、エラーメッセージ中のパスの一部を省略しています
(...
が省略部分です)
In file included from C:/.../c++/ext/alloc_traits.h:36:0, from ... from C:\Users...\main.cpp:1: C:/.../c++/bits/alloc_traits.h: In instantiation of 'struct std::allocator_traits<std::allocator<int&> >': ... C:\Users...\main.cpp:24:35: required from 'void MergeSort(ContainerItr, ContainerItr) [with ContainerItr = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]' C:\Users...\main.cpp:62:34: required from here C:/.../c++/bits/alloc_traits.h:392:27: error: forming pointer to reference type 'int&' using pointer = _Tp*; ^ C:/.../c++/bits/alloc_traits.h:395:39: error: forming pointer to reference type 'int&' using const_pointer = const _Tp*; ^ In file included from C:/.../c++/bits/basic_string.h:40:0, from ... from C:\Users...\main.cpp:1: C:/.../c++/ext/alloc_traits.h: In instantiation of 'struct __gnu_cxx::__alloc_traits<std::allocator<int&> >': ... C:\Users...\main.cpp:24:35: required from 'void MergeSort(ContainerItr, ContainerItr) [with ContainerItr = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]' C:\Users...\main.cpp:62:34: required from here C:/.../c++/ext/alloc_traits.h:66:23: error: no members matching '__gnu_cxx::__alloc_traits<std::allocator<int&> >::_Base_type {aka std::allocator_traits<std::allocator<int&> >}::allocate' in '__gnu_cxx::__alloc_traits<std::allocator<int&> >::_Base_type {aka struct std::allocator_traits<std::allocator<int&> >}' using _Base_type::allocate; ^~~~~~~~ C:/.../c++/ext/alloc_traits.h:67:23: error: no members matching '__gnu_cxx::__alloc_traits<std::allocator<int&> >::_Base_type {aka std::allocator_traits<std::allocator<int&> >}::deallocate' in '__gnu_cxx::__alloc_traits<std::allocator<int&> >::_Base_type {aka struct std::allocator_traits<std::allocator<int&> >}' using _Base_type::deallocate; ^~~~~~~~~~ In file included from C:/.../c++/x86_64-w64-mingw32/bits/c++allocator.h:33:0, from ... from C:\Users...\main.cpp:1: C:/.../c++/ext/new_allocator.h: In instantiation of 'class __gnu_cxx::new_allocator<int&>': ... C:\Users...\main.cpp:24:35: required from 'void MergeSort(ContainerItr, ContainerItr) [with ContainerItr = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]' C:\Users...\main.cpp:62:34: required from here C:/.../c++/ext/new_allocator.h:63:26: error: forming pointer to reference type 'int&' typedef _Tp* pointer; ^~~~~~~ C:/.../c++/ext/new_allocator.h:64:26: error: forming pointer to reference type 'int&' typedef const _Tp* const_pointer; ^~~~~~~~~~~~~ In file included from C:/.../c++/string:41:0, from ... from C:\Users...\main.cpp:1: C:/.../c++/bits/allocator.h: In instantiation of 'class std::allocator<int&>': ... C:\Users...\main.cpp:24:35: required from 'void MergeSort(ContainerItr, ContainerItr) [with ContainerItr = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]' C:\Users...\main.cpp:62:34: required from here C:/.../c++/bits/allocator.h:113:26: error: forming pointer to reference type 'int&' typedef _Tp* pointer; ^~~~~~~ C:/.../c++/bits/allocator.h:114:26: error: forming pointer to reference type 'int&' typedef const _Tp* const_pointer; ^~~~~~~~~~~~~ In file included from C:/.../c++/vector:64:0, from C:\Users...\main.cpp:2: C:/.../c++/bits/stl_vector.h: In instantiation of 'class std::vector<int&, std::allocator<int&> >': C:\Users...\main.cpp:24:35: required from 'void MergeSort(ContainerItr, ContainerItr) [with ContainerItr = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]' C:\Users...\main.cpp:62:34: required from here C:/.../c++/bits/stl_vector.h:247:20: error: no members matching 'std::vector<int&, std::allocator<int&> >::_Base {aka std::_Vector_base<int&, std::allocator<int&> >}::_M_allocate' in 'std::vector<int&, std::allocator<int&> >::_Base {aka struct std::_Vector_base<int&, std::allocator<int&> >}' using _Base::_M_allocate; ^~~~~~~~~~~ C:/.../c++/bits/stl_vector.h:248:20: error: no members matching 'std::vector<int&, std::allocator<int&> >::_Base {aka std::_Vector_base<int&, std::allocator<int&> >}::_M_deallocate' in 'std::vector<int&, std::allocator<int&> >::_Base {aka struct std::_Vector_base<int&, std::allocator<int&> >}' using _Base::_M_deallocate; ^~~~~~~~~~~~~ C:/.../c++/bits/stl_vector.h:920:7: error: forming pointer to reference type 'int&' data() _GLIBCXX_NOEXCEPT ^~~~ C:/.../c++/bits/stl_vector.h:924:7: error: forming pointer to reference type 'int&' data() const _GLIBCXX_NOEXCEPT ^~~~ C:/.../c++/bits/stl_vector.h:953:7: error: 'void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = int&; _Alloc = std::allocator<int&>; std::vector<_Tp, _Alloc>::value_type = int&]' cannot be overloaded push_back(value_type&& __x) ^~~~~~~~~ C:/.../c++/bits/stl_vector.h:939:7: error: with 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int&; _Alloc = std::allocator<int&>; std::vector<_Tp, _Alloc>::value_type = int&]' push_back(const value_type& __x) ^~~~~~~~~ In file included from C:/.../c++/bits/range_access.h:36:0, from ... from C:\Users...\main.cpp:1: C:/.../c++/initializer_list: In instantiation of 'class std::initializer_list<int&>': C:\Users...\main.cpp:24:35: required from 'void MergeSort(ContainerItr, ContainerItr) [with ContainerItr = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]' C:\Users...\main.cpp:62:34: required from here C:/.../c++/initializer_list:54:26: error: forming pointer to reference type 'int&' typedef const _E* iterator; ^~~~~~~~ C:/.../c++/initializer_list:55:26: error: forming pointer to reference type 'int&' typedef const _E* const_iterator; ^~~~~~~~~~~~~~ mingw32-make.exe[3]: *** [CMakeFiles\untitled1.dir\build.make:62: CMakeFiles/untitled1.dir/main.cpp.obj] Error 1 mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:67: CMakeFiles/untitled1.dir/all] Error 2 mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:79: CMakeFiles/untitled1.dir/rule] Error 2 mingw32-make.exe: *** [Makefile:117: untitled1] Error 2
補足
コンパイラはgcc(MinGW)、IDEはCLionを使用しています。
コンパイラは次のマクロで調べたところ、C++17までサポートしていました。
C++
1// バージョンチェック 2#ifdef __cpp_rvalue_references 3 cout<<"C++11 supported"<<endl; 4#endif 5#ifdef __cpp_binary_literals 6 cout<<"C++14 supported"<<endl; 7#endif 8#ifdef __cpp_hex_float 9 cout<<"C++17 supported"<<endl; 10#endif
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/20 16:16 編集
2019/03/20 23:16