使用数组作为映射键:即使使用自定义分配器也不可能?
Using array as map key: impossible even with custom allocator?
此问题与these three questions有关。
我试图使用固定长度的数组作为 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
的 =
(赋值)可能是 "rerouted" 到 MyAlloc::allocate()
,但这是一个疯狂的、毫无根据的猜测,这似乎是错误的。有没有办法修改自定义分配器来解决第一个代码块的编译错误?
我有一个半生不熟的想法,即 myuuid
操作数上的 operator=
可以是自定义分配器的 "rerouted",但我不知道这是否适用于 PODs(myuuid
只是类型定义为 POD`)。
此处的编译错误太多post,但很明显,第一个错误是:
/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
键吗? (也许有一个我应该实现的可选功能?)或者提到的链接中的替代方案是唯一的解决方案吗? (这些问题的答案中没有提出,但由于自定义分配器有点深奥,我认为值得单独提问)
原始 C 数组不是行为良好的类型。您不能分配它们或对它们做无数其他您想做的事情。
其次,std::less<char[16]>
不行。
C++ 提供 std::array
,它是 struct
.
中原始 C 数组的薄包装器
typedef std::array<char, 16> myuuid;
它甚至带有一个内置的 <
,通常可以正常工作。
所以我们得到:
std::map<myuuid, int> map;
一切正常。
std::array
有 []
和 .data()
和 .size()
和 .begin()
和 .end()
并且通常表现良好。
如果需要转为指针,调用.data()
即可。
此问题与these three questions有关。
我试图使用固定长度的数组作为 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
的 =
(赋值)可能是 "rerouted" 到 MyAlloc::allocate()
,但这是一个疯狂的、毫无根据的猜测,这似乎是错误的。有没有办法修改自定义分配器来解决第一个代码块的编译错误?
我有一个半生不熟的想法,即 myuuid
操作数上的 operator=
可以是自定义分配器的 "rerouted",但我不知道这是否适用于 PODs(myuuid
只是类型定义为 POD`)。
此处的编译错误太多post,但很明显,第一个错误是:
/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
键吗? (也许有一个我应该实现的可选功能?)或者提到的链接中的替代方案是唯一的解决方案吗? (这些问题的答案中没有提出,但由于自定义分配器有点深奥,我认为值得单独提问)
原始 C 数组不是行为良好的类型。您不能分配它们或对它们做无数其他您想做的事情。
其次,std::less<char[16]>
不行。
C++ 提供 std::array
,它是 struct
.
typedef std::array<char, 16> myuuid;
它甚至带有一个内置的 <
,通常可以正常工作。
所以我们得到:
std::map<myuuid, int> map;
一切正常。
std::array
有 []
和 .data()
和 .size()
和 .begin()
和 .end()
并且通常表现良好。
如果需要转为指针,调用.data()
即可。