首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >合成std::integral_constant值

合成std::integral_constant值
EN

Stack Overflow用户
提问于 2015-06-19 10:35:10
回答 1查看 343关注 0票数 1

考虑一下这段代码

代码语言:javascript
复制
#include <iostream>
#include <type_traits>

enum Thing {Thing0, Thing1, Thing2, NumThings};
enum Object {Object0, Object1, Object2, NumObjects};

template <Thing> struct ThingValue;

template <> struct ThingValue<Thing0> : std::integral_constant<int, 5> {};
template <> struct ThingValue<Thing1> : std::integral_constant<int, 2> {};
template <> struct ThingValue<Thing2> : std::integral_constant<int, 12> {};

template <Object> struct ObjectValue;

template <> struct ObjectValue<Object0> : std::integral_constant<Thing, Thing2> {};
template <> struct ObjectValue<Object1> : std::integral_constant<Thing, Thing0> {};
template <> struct ObjectValue<Object2> : std::integral_constant<Thing, Thing1> {};

int main() {
    std::cout << ThingValue<ObjectValue<Object0>::value>::value << '\n';  // 12
}

我试图定义,ComposeValues<T, Value, Pack...>,以便main()中的上述内容可以写成ComposeValues<Object, Object0, ThingValue, ObjectValue>::value。因此,这可以扩展到任意数量的这样的组合。这不是一件绝对重要的事情,但我想这将是一个很好的小练习来定义这样的事情。但我在语法上有困难:

代码语言:javascript
复制
template <typename T, T Value, template <typename> class...> struct ComposeValues;

template <typename T, T Value, template <typename> class First, template <typename> class... Rest>
struct ComposeValues<T, Value, First, Rest...> {
    static auto value = First<typename ComposeValues<T, Value, Rest...>::value>::value;
};

template <typename T, T Value, template <T> class Last>
struct ComposeValues<T, Value, Last> : std::integral_constant<T, Last<Value>::value> {};  // Won't compile.

这有可能是我想做的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-19 11:25:18

您所遇到的问题是不能混合采用不同非类型参数的模板模板。在您的示例中,这意味着ObjectValueThingValue不能绑定到template <typename> class...

解决这一问题的一种方法是在某种类型的模板中对枚举进行编码,这种模板可以不加区分地保存这两个模板。一种可能的方法是将枚举作为int来处理,让用户担心传入合理的类型。

首先,我们创建当前类型的包装器:

代码语言:javascript
复制
template <typename> struct ThingValueWrapper;
template <int I>
struct ThingValueWrapper<std::integral_constant<int,I>> 
    : ThingValue<static_cast<Thing>(I)>
{};

template <typename> struct ObjectValueWrapper;
template <int I>
struct ObjectValueWrapper<std::integral_constant<int, I>> 
    : ObjectValue<static_cast<Object>(I)>
{};

然后我们可以做一些和你原来的非常相似的事情:

代码语言:javascript
复制
template <typename T, T Value, template <typename> class...> struct ComposeValues;

template <typename T, T Value, 
          template <typename> class First, 
          template <typename> class... Rest>
struct ComposeValues<T, Value, First, Rest...>
    : std::integral_constant<int,
                             First<typename ComposeValues<T, Value, Rest...>::type>::value>
{};

template <typename T, T Value>
struct ComposeValues<T, Value> : std::integral_constant<int, static_cast<int>(Value)> {};

与原始用例不同的是,我们需要使用包装器而不是原始的枚举特性:

代码语言:javascript
复制
ComposeValues<Object, Object0, ThingValueWrapper, ObjectValueWrapper>::value
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30936019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档