构建constexpr模板结构(C ++ 11)

时间:2017-12-04 21:57:54

标签: c++11 templates variadic-templates constexpr

我有这个代码,它有效...到目前为止很好:

struct _TYPEIDSTR {};
typedef _TYPEIDSTR *TYPE_ID;
template<class T> _TYPEIDSTR _TYPE_ID;

template<class T> constexpr TYPE_ID getTypeID() { return &_TYPE_ID<T>; }
像这样在主要方面打电话:

constexpr TYPE_ID id1 = getTypeID<int>();
constexpr TYPE_ID id2 = getTypeID<int>();
RLOG("ID1 : " << id1);
RLOG("ID2 : " << id2);

工作得很好,我为getTypeID()调用中使用的每种类型都有一个唯一的标识符。 现在我想构建一个结构,它带来一些关于函数的信息:

template<typename RES, typename... ARGS> struct _GlobalOverlayInfo {
    bool _member;
    RES(*_fn)(ARGS...);
    size_t _nargs;
    TYPE_ID _argIDs;
    constexpr _GlobalOverlayInfo(RES(*fn)(ARGS...)) :
    _member(false),
    _fn(fn),
    _nargs(sizeof...(ARGS)),
    _argIDs {getTypeID<ARGS>()...}
    {}
};

template<typename RES, typename... ARGS>
constexpr auto getOverlayInfo(RES(*fn)(ARGS...)) {
    return & _GlobalOverlayInfo<RES, ARGS...>(fn); <<---ERROR1
}

使用此功能:

int pippo(int x) {
    return 0;
}

并且这样打电话:

constexpr auto x = getOverlayInfo(pippo); <<--- ERROR2

我得到了2个标记错误; ERROR1是“取一个临时的地址”(但不应该是编译时评估?)而ERROR2是“错误:'&amp;'不是常量表达式”。 我尝试过很多方面,但我无法成功。哪里错了? 有没有办法(在C ++ 11中)实现这个结果? 我只需要指向为每个RES和ARGS ...参数生成的唯一结构的指针。

1 个答案:

答案 0 :(得分:1)

不确定你想要做什么。

无论如何,如果你想使用C ++ 11(并避免使用C ++ 14或更新版本),你就不能使用模板变量,如

template<class T> _TYPEIDSTR _TYPE_ID;

这是一个C ++ 14功能。

如果您需要constexpr模板标识符,可以使用{C} 11开始提供的std::type_index

如果你不能使用std::type_index ......那么我能想象的最好的是一个带有static变量的模板类和一个返回指针的static方法它。

这样的东西
template <typename>
struct typeId
 {
   static constexpr int const val {};

   static constexpr int const * getId ()
    { return &val; }
 };

template <typename T>
constexpr int const typeId<T>::val;

您可以获得constexpr个值,并且可以检查是不同的

constexpr auto const idInt = typeId<int>::getId();
constexpr auto const idLong = typeId<long>::getId();

std::cout << (idInt != idLong) << std::endl; // print 1

对于功能案例......

函数有类型,单个函数可以是模板参数。

因此,如果您需要函数的constexpr标识符,可以按如下方式创建包装器

template <typename Ft, Ft f>
struct funcT
 { };

并使用前面的typeId,从不同的函数中获取不同的constexpr值,如下所示

int  foo (int) { return 0; }
int  bar (int) { return 0; }
long baz (int, long, long long) { return 0L; }

// ...

constexpr auto idFoo = typeId<funcT<decltype(&foo), &foo>>::getId();
constexpr auto idBar = typeId<funcT<decltype(&bar), &bar>>::getId();
constexpr auto idBaz = typeId<funcT<decltype(&baz), &baz>>::getId();

std::cout << (idFoo != idBar) << std::endl; // print 1
std::cout << (idFoo != idBaz) << std::endl; // print 1