2017-05-25 10 views
0

この質問は、thesethreequestionsに関連しています。配列をマップキーとして使用:カスタムアロケータでも不可能?

以下の非コンパイルコードで示されたように、私は、std::mapのキーとして固定長配列を使用しようとしていた。

#include <cstdlib> 
#include <iostream> 
#include <map> 

typedef char myuuid[ 16 ]; 

template <class T> 
class MyAlloc 
{ 
public: 
    typedef T value_type; 
    typedef T* pointer; 
    typedef T& reference; 
    typedef const T* const_pointer; 
    typedef const T& const_reference; 
    template <class U> struct rebind { typedef MyAlloc<U> other; }; 
    MyAlloc() {} 
    MyAlloc(const MyAlloc& other) {} 
    T* allocate(std::size_t n) { return static_cast<T*>(std::malloc(n * sizeof(value_type))); } 
    void deallocate(T* p, std::size_t n) { std::free(p); } 
}; 

int main(int argc, char* argv[]) 
{ 
    std::map<myuuid, int, std::less<myuuid>, MyAlloc<myuuid> > map; 
    myuuid myu; 
    map[ myu ] = 5; 

    return 0; 
} 

が一瞬カスタムアロケータを無視して、私は正しくリンク理解していれば、答え、std::map<myuuid, int> map; myuuid myu; map[myu] = 5;が失敗した理由は、次のことが不可能であることにダウンしています:

int main(int argc, char* argv[]) 
{ 
    char a[3]; 
    char b[3]; 
    b = a; // Illegal - won't compile 
    return 0; 
} 

質問

私は上記が違法である理由を理解していますが、これはstd::map<myuuid, int> map; myuuid myu; map[myu] = 5;が違法な理由を示していますか?

質問

私は、カスタムアロケータを実装した場合、私はstd::map<myuuid, int> map; myuuid myu; map[myu] = 5;をコンパイルすると逃げることができるかもしれないと思いました。 myuuid=(割り当て)がMyAlloc::allocate()に「再ルーティングされました」と推測されましたが、それは偽であると思われる野生の推測された推測でした。最初のコードブロックのコンパイルエラーを解決するためにカスタムアロケータを変更できる方法はありますか?

は、私はそのoperator=myuuid上のオペランドがカスタムアロケータに「再ルーティング」ことができることが中途半端な概念を持っているが、私はmyuuidがちょうどPOD`にtypedefされている(これはのPODのために真であるかどうかを知りません)。

コンパイルエラーがここに投稿するにはあまりにも膨大ですが、tellingly、最初のエラーがある:

興味深いことに
/usr/include/c++/4.8.3/bits/stl_pair.h: In instantiation of \u2018std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = const char [16]; _T2 = int]\u2019: 
/usr/include/c++/4.8.3/bits/stl_map.h:469:59: required from \u2018std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = char [16]; _Tp = int; _Compare = std::less<char [16]>; _Alloc = MyAlloc<char 
[16]>; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = char [16]]\u2019 
main.cpp:27:12: required from here 
/usr/include/c++/4.8.3/bits/stl_pair.h:113:31: error: array used as initializer 
     : first(__a), second(__b) { } 

error: array used as initializerは私がカスタムアロケータを導入する前から解決しようとしていたオリジナルのコンパイルエラーです。これは再帰的な問題のようです。

質問std::mapキーは、カスタムアロケータを使用することによって、何とかオフに引っ張られるよう

は、アレイの使用はできますか? (おそらく、実装する必要のあるオプションの機能がありますか?)または、唯一の解決策として注目されているリンクの代替案はありますか? (これらの質問の答えは出ませんでしたが、カスタムアロケータはあまりにも難解なので別の質問があると思いました)

+1

TL; DRしかし、 'typedefでのstd ::配列 myuuid;' – juanchopanza

+0

はちょうど '使用のstd ::配列'や 'のstd :: STRING' – Walter

+0

@juanchopanza - 私はそのように受け入れることを望んだ、ありがとう代わりに、しかし、この質問では、私は興味を持っている(理解する/欲しい)カスタムアロケータでこれを解決することができます/方法。 – StoneThrow

答えて

5

Raw C配列は正常に動作しません。あなたはそれらを割り当てることはできませんし、あなたが望むと思うもので無数の他のことをすることはできません。

次に、std::less<char[16]>は機能しません。

C++はstructで生のC配列を囲む薄いラッパーであるstd::arrayを提供します。

typedef std::array<char, 16> myuuid; 

通常、正しいことをする<が組み込まれています。

だから我々が得る:

std::map<myuuid, int> map; 

、物事が働いています。

std::array[].data().size().begin().end()を持っており、一般的によく動作します。

ポインタに変換する必要がある場合は、.data()に電話するだけです。

+0

@juanchopanzaそうです。私は頻繁に配列をソートしません。 – Yakk

関連する問題