假设我有一个类似的模板类:
template <typename T>
struct TypeInformation {
static int s_someArbitraryData;
}
template <typename T> TypeInformation<T>::s_someArbitraryData = 0;
然后,在以后的某个时刻,我可以执行以下操作:
SomeFunction() {
SetUpData<int>(); // Populates s_someArbitraryData for int.
}
通过仅调用SetUpData,我为给定类型设置了s_someArbitraryData的一个副本。如果可能的话,我想做的是做类似的事情,但建立一种映射类型的方法。像这样的东西,目前不起作用:
template <typename T>
struct MyTypeMap {}
// ...
SomeFunction() {
SetUpTypemap<int, float>(); // Creates a typedef on MyTypeMap<int>
MyTypeMap<int>::type myFloatValue = 1.0f; // A float value
}
我可以通过执行以下操作来完成right now:
template <>
struct MyTypeMap<int> {
typedef float type;
}
但这对我的情况有一些烦人的缺点。我怀疑我想要的东西是不可能的,但是如果我不知道有什么深奥的模板魔术可以解决这个问题,我也不会感到惊讶。
最佳答案
这可能与您要查找的内容相差不远:
#include<type_traits>
template<typename T>
struct tag { using type = T; };
template<typename...>
struct MapPart;
template<typename T, typename U, typename... O>
struct MapPart<T, U, O...>: MapPart<O...> {
using MapPart<O...>::get;
static constexpr tag<U> get(tag<T>) { return {}; }
};
template<>
struct MapPart<> {
static constexpr void get();
};
template<typename... T>
struct Map: MapPart<T...> {
template<typename U>
using type = typename decltype(Map<T...>::template get<U>())::type;
template<typename U>
static constexpr auto get() {
return MapPart<T...>::get(tag<U>{});
}
};
int main() {
using MyTypeMap = Map<int, float>;
static_assert(std::is_same<MyTypeMap::type<int>, float>::value, "!");
MyTypeMap::type<int> myFloatValue = 1.0f;
}
最终语法略有不同。你有这个:
MyTypeMap::type<int>
代替这个:
MyTypeMap<int>::type
无论如何,我认为这是可以接受的。
MyTypeMap
类型仅在using声明的范围内可见。我以为这是原始SetUpTypemap<int, float>
函数的意图:仅在函数int
中设置float
和SomeFunction
之间的绑定。通过使用这种方法,您可以一次建立多个关系。
举个例子:
using MyTypeMap = Map<int, float, float, int>;
// ....
MyTypeMap::type<int> myFloatValue = 1.0f;
MyTypeMap::type<float> myIntValue = 1;
还要注意,为一个类型设置的第一个关系是最强的。
换句话说,如果您这样做:
using MyTypeMap = Map<int, float, int, char>;
类型
MyTypeMap::type<int>
将为float
,它将隐藏int
和char
之间的关系。这不是一个完美的解决方案,但也许可以解决您的问题。