C++11:根据项目计数在 std::array 和 std::unordered_map 之间实现选择器
C++11: Implementing a Selector between std::array and std::unordered_map according to item count
我正在尝试创建一个映射 class,它会根据可能的值范围自动 select 正确的实现。如果取值范围最大为 256,则使用 std::array
,否则,使用 std::unordered_map
.
template<typename KeyType, typename ValType>
class MapImpl : public std::unordered_map<KeyType,ValType>
{
void foo() { std::cout << "Map foo" << std::endl; }
};
template<typename ValType, std::size_t Size>
class ArrImpl : public std::array<ValType,Size>
{
public:
void foo() { std::cout << "Arr foo" << std::endl; }
};
template<typename KeyType, typename ValType,
KeyType min_value = boost::integer_traits<KeyType>::const_min,
KeyType max_value = boost::integer_traits<KeyType>::const_max>
class MappingSelector
{
public:
void bar() { map.foo(); }
private:
typedef std::conditional<(max_value-min_value < 256),
ArrImpl<ValType,max_value-min_value+1>,
MapImpl<KeyType,ValType>
> MappingType;
MappingType map;
};
到目前为止一切顺利(?)
然后我实例化它:
MappingSelector<unsigned char, double> ms;
ms.bar();
但是,编译器似乎不喜欢这样,并告诉我我的 MappingType
没有名为 foo
的成员。
std::conditional
没有直接定义结果类型,但它定义了一个结构,它有一个 typedef type
是相应的类型。
这意味着你必须限定特定类型,所以你的typedef应该是
typedef std::conditional<(max_value-min_value < 256),
ArrImpl<ValType,max_value-min_value+1>,
MapImpl<KeyType,ValType>
> MappingType;
typename MappingType::type map;
^ requires typename for unambiguation
^ ::type is the real typedef
或者您可以通过使用 ::type
限定直接输入定义 MappingType
,结果相同。实际上,由于您使用的是 C++11,因此您还可以使用 using
,例如:
using MappingType = typename std::conditional<(max_value-min_value < 256),
ArrImpl<ValType,max_value-min_value+1>,
MapImpl<KeyType,ValType>
>::type;
MappingType map;
问题可能在于
typedef std::conditional<(max_value-min_value < 256),
ArrImpl<ValType,max_value-min_value+1>,
MapImpl<KeyType,ValType>
> MappingType;
你可能指的是哪里
typedef typename std::conditional<(max_value-min_value < 256),
ArrImpl<ValType,max_value-min_value+1>,
MapImpl<KeyType,ValType>
>::type MappingType;
您实际上 typedef
这里不是您所指的类型之一 (IIUC);相当。您 typedef
编辑了类型的 "if statement"。
查看 here 如何使用此构造的示例。
std::conditional
是一个特征 class,它将所选类型公开为 ::type
。所以你需要这样做:
typedef typename std::conditional<...>::type MappingType;
如果你有 C++14,你可以通过使用别名模板来简化它:
typedef std::conditional_t<...> MappingType;
我正在尝试创建一个映射 class,它会根据可能的值范围自动 select 正确的实现。如果取值范围最大为 256,则使用 std::array
,否则,使用 std::unordered_map
.
template<typename KeyType, typename ValType>
class MapImpl : public std::unordered_map<KeyType,ValType>
{
void foo() { std::cout << "Map foo" << std::endl; }
};
template<typename ValType, std::size_t Size>
class ArrImpl : public std::array<ValType,Size>
{
public:
void foo() { std::cout << "Arr foo" << std::endl; }
};
template<typename KeyType, typename ValType,
KeyType min_value = boost::integer_traits<KeyType>::const_min,
KeyType max_value = boost::integer_traits<KeyType>::const_max>
class MappingSelector
{
public:
void bar() { map.foo(); }
private:
typedef std::conditional<(max_value-min_value < 256),
ArrImpl<ValType,max_value-min_value+1>,
MapImpl<KeyType,ValType>
> MappingType;
MappingType map;
};
到目前为止一切顺利(?) 然后我实例化它:
MappingSelector<unsigned char, double> ms;
ms.bar();
但是,编译器似乎不喜欢这样,并告诉我我的 MappingType
没有名为 foo
的成员。
std::conditional
没有直接定义结果类型,但它定义了一个结构,它有一个 typedef type
是相应的类型。
这意味着你必须限定特定类型,所以你的typedef应该是
typedef std::conditional<(max_value-min_value < 256),
ArrImpl<ValType,max_value-min_value+1>,
MapImpl<KeyType,ValType>
> MappingType;
typename MappingType::type map;
^ requires typename for unambiguation
^ ::type is the real typedef
或者您可以通过使用 ::type
限定直接输入定义 MappingType
,结果相同。实际上,由于您使用的是 C++11,因此您还可以使用 using
,例如:
using MappingType = typename std::conditional<(max_value-min_value < 256),
ArrImpl<ValType,max_value-min_value+1>,
MapImpl<KeyType,ValType>
>::type;
MappingType map;
问题可能在于
typedef std::conditional<(max_value-min_value < 256),
ArrImpl<ValType,max_value-min_value+1>,
MapImpl<KeyType,ValType>
> MappingType;
你可能指的是哪里
typedef typename std::conditional<(max_value-min_value < 256),
ArrImpl<ValType,max_value-min_value+1>,
MapImpl<KeyType,ValType>
>::type MappingType;
您实际上 typedef
这里不是您所指的类型之一 (IIUC);相当。您 typedef
编辑了类型的 "if statement"。
查看 here 如何使用此构造的示例。
std::conditional
是一个特征 class,它将所选类型公开为 ::type
。所以你需要这样做:
typedef typename std::conditional<...>::type MappingType;
如果你有 C++14,你可以通过使用别名模板来简化它:
typedef std::conditional_t<...> MappingType;