编译模板参数的时间计数/编号

时间:2015-06-29 10:29:58

标签: c++ templates c-preprocessor

对于低级应用程序,我在编译时将索引的类型定义为类型:

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];
}

2 个答案:

答案 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{};类型字段中。

在相关字段的名称类型列表中获取值搜索。

不变量,就像每个标记出现一次,并且查找中使用的每个标记都在名称中使用,可以进行编译时检查。

您甚至可以使用缓冲区位置信息创建一个字段集合,以允许获取值从标记中查找缓冲区而不会被告知,并强制执行跨字段标记唯一性。