36558

[code]

    typedef struct address {
        int number;     
        string name;            // 名前
        string phoneNumber;     // 電話番号
    }Address;
    
[/code]

このような構造体を用意し、

[code]

    list<Address> addressList;
    
[/code]

このようにlistで宣言してソートは以下のようにしようと思いました。

[code]

    sort( addressList.begin(), addressList.end(), 
        []( Address numA, Address numB )->int {
        return ( numA.number > numB.number );
    });
    
[/code]

VS2017を使用していますが以下のようなエラーが出てきましたが、どのような意味となるのでしょうか。  
又、解決策としてはどのようにするのが正解なのでしょうか。よろしくお願いいたします。

[code]

    重大度レベル  コード 説明  プロジェクト  ファイル    行   抑制状態
    エラー C2784   'unknown-type std::operator -(const std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)': テンプレート 引数を 'const std::move_iterator<_RanIt> &' に対して 'std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<address>>>' から減少できませんでした listSortTest    C:\Program Files\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.10.25017\include\algorithm  2908    
    
[/code]


CC BY-SA 3.0
2017-07-21T05:13:01.253
36556
2017-07-21T06:33:11.357
2017-07-21T06:19:21.543
49
24381
question
c++ c++11
list<構造体>に対してのソート


[`std::sort`関数](https://cpprefjp.github.io/reference/algorithm/sort.html) では
`std::list<T>` コンテナをソートすることができません。代わりに
[`std::list<T>::sort`メンバ関数](https://cpprefjp.github.io/reference/list/sort.html)
を呼び出す必要があります。

[code]

    addressList.sort([](const Address& numA, const Address& numB) {
      return (numA.number > numB.number);  // 降順ソート
    });
    
[/code]

* * *

> 以下のようなエラーが出てきましたが、どのような意味となるのでしょうか。
>

>> エラー C2784 'unknown-type std::operator -(const std::move_iterator<_RanIt>
&,const std::move_iterator<_RanIt2> &)': テンプレート 引数を 'const
std::move_iterator<_RanIt> &' に対して 'std::_List_unchecked_iterator>>'
から減少できませんでした

`std::sort`はテンプレート関数として定義されていますが、エラーメッセージは「関数を実体化するプロセス途中で型の導出に失敗したこと」を表します。残念ながら、このエラーメッセージから直接原因を読み取るのはほとんど不可能かと思います。真の原因は「`std::sort`関数はRandom
Access Iteratorを引数に要求するが、`std::list<T>`のイテレータはRandom Access
Iteratorではないため(Bidirectional
Iterator)」です。[こちらの記事](https://cpplover.blogspot.jp/2007/03/concepts-extending-
c-templates-for.html)もご参考に。

現在(C++14)のC++言語仕様では、このような状況に対して適切なエラーメッセージを出すことが非常に難しいというのが実情です。将来的にはコンセプト(Concept)という機能が追加され、このあたりのエラーメッセージ改善につながると考えられます。

* * *

> このようにlistで宣言してソートは以下のようにしようと思いました。
[code]

>     sort( addressList.begin(), addressList.end(),
>       []( Address numA, Address numB )->int {
>       return ( numA.number > numB.number );
>     });
>  
[/code]

上記でも動きはしますが、いくつか気になる点があります。

  * 実行時パフォーマンスの観点から、引数はconst参照型(`const Address&`)が好ましいです。値型(`Address`)では比較のたびにオブジェクト・コピーと破棄が行われてしまいます。
  * セマンティクス上、ラムダ式の戻値型は`int`ではなく`bool`が好ましいです。好みの問題もありますが、`return`文の比較式から推論させる（戻り値型は省略）した方がシンプルです。
  * 比較演算に「より大きい`>`」を利用した場合、降順ソートが行われます。この振る舞いがあなたの意図通りなら大丈夫です。


CC BY-SA 3.0
2017-07-21T05:58:42.973
36558
2017-07-21T06:33:11.357
2017-07-21T06:33:11.357
49
49
36556
answer