对于低级应用程序,我在编译时将索引的类型定义为类型:
template <int IDX_, class T_>
class Idx{
using TYPE = T_;
static const int IDX = IDX_;
}
然后用法:
using region1_field1 = Idx<0, double>;
using region1_field2 = Idx<1, double>;
using region1_field3 = Idx<2, float>;
using region2_field1 = Idx<0, char>;
using region2_field2 = Idx<1, char>;
这个Idx
模板对我来说基本上做得很好,但是你必须手动设置IDX_
参数很烦人且有点危险。 有没有办法在编译时自动计算和设置该参数?如您所见,我需要region1_*
和region2_*
的该计数器的多个实例。
最后,该类用于:
template <class IDX_>
typename IDX_::TYPE getValue(IDX_ idx, int pos){
return (reinterpret_cast<typename IDX_::TYPE*>(data_ptrs[IDX_]))[pos];
}
答案 0 :(得分:2)
在我看来,您正在寻找boost::mpl::vector
。
所以我这样做(考虑到我只是想象你的用例):
必要boost::mpl
:
#include <boost/mpl/vector.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>
所以你可以拥有你的“地区”:
using region1 = boost::mpl::vector<double, double, float>;
using region2 = boost::mpl::vector<char, char>;
Idx
类有Idx<region1,1>
个捷径:
template <typename Region, int Pos>
using Idx = boost::mpl::pair<Region,boost::mpl::int_<Pos>>;
访问Idx
类型:
template <typename Idx>
using IdxType = typename boost::mpl::at<typename Idx::first, typename Idx::second>;
现在 - 它是如何运作的:
我想你的dataptrs就像这样(简化版;):
struct DataPtrs
{
char data[20]= "Hello from MPL";
template <typename Idx>
void* operator[](Idx idx)
{
return data;
}
};
DataPtrs data_ptrs;
访问它 - 将以这种方式看待:
template <class Idx>
typename IdxType<Idx>::type getValue(int pos) {
return reinterpret_cast<typename IdxType<Idx>::type*>(data_ptrs[Idx()])[pos];
}
main
:
#include <iostream>
int main() {
using region2_0 = Idx<region2,0>;
std::cout << getValue<region2_0>(1);
}
所以 - 我的建议 - 使用boost::mpl
- 如果您不能在项目中使用boost,则从中复制必要的部分。当然,您必须将我的提案与您的需求保持一致......
最后 - 您可以在ideone
尝试全部答案 1 :(得分:1)
让您的代码struct foo {};
为空。
将它们存储在template<class...>struct types{};
类型列表中。
将其存储在template<class Names, class T>struct field{};
类型字段中。
在相关字段的名称类型列表中获取值搜索。
不变量,就像每个标记出现一次,并且查找中使用的每个标记都在名称中使用,可以进行编译时检查。
您甚至可以使用缓冲区位置信息创建一个字段集合,以允许获取值从标记中查找缓冲区而不会被告知,并强制执行跨字段标记唯一性。