ぷるぷるの雑記

低レイヤーがんばるぞいなブログ. 記事のご利用は自己責任で.

<algorithm>でポインタを使うときは型に注意

c++の<algorithm>中にはイテレータを引数に渡すことでコンテナの全要素に対して探索をする関数があります. 探索する対象が配列の場合はポインタを引数に渡すことが可能です.

例えばstd::any_of()は次のように使用することができます.

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int main()
{
    vector<int> vec_int    = {0x00ffffff};
    int         arr_int[1] = {0x00ffffff};
    cout << boolalpha;

    bool retvec = any_of( v.begin(),   v.end(), [](int x){return x<0x100;});
    bool retarr = any_of(   arr_int, arr_int+1, [](int x){return x<0x100;});

    cout << retvec << endl; /* false */
    cout << retarr << endl; /* false */

    return 0;    
}

このプログラムは配列やコンテナに0x100未満の要素があればtrue、そうでなければfalseを表示するプログラムです. コンテナとポインタでどちらもfalseが表示され、正しく評価されていることがわかります.

しかし、ポインタを引数に使用する場合 引数に渡したポインタの型によって評価する型が変動します. 例えば次のようにポインタをchar型へのポインタへキャストしてプログラムを実行すると、0x00ffffffという数値ではなく、(リトルエンディアンの場合)0xff, 0xff, 0xff, 0x00 という数値が評価され、trueが表示されます.

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int main()
{
    vector<int> vec_int    = {0x00ffffff};
    int         arr_int[1] = {0x00ffffff};
    cout << boolalpha;

    bool retvec = any_of( v.begin(),   v.end(), [](int x){return x<0x100;});
    bool retarr = any_of(   (char*)arr_int, (char*)(arr_int+1), [](int x){return x<0x100;});

    cout << retvec << endl; /* false */
    cout << retarr << endl; /* true */

    return 0;    
}

ラムダ式の引数の型ではなく、ポインタの型に依存するので注意しましょう.

参考

cpprefjp.github.io