繁体   English   中英

模板化类的可变参数模板

[英]Variadic Template of Templated Classes

我有一个结构,定义如下:

template<typename T>
struct Variable
{
    char *name;

    constexpr Variable(char *setName) : name(setName)
    {

    }
};

我想创建一个类,其模板参数是这些结构的列表。 到目前为止,我能得到的最接近的是:

template<template<typename TF> Variable First, template<TA...> typename Variable ... Args>
class UniformBuffer
{
};

可以将UniformBuffer声明如下:

// vec3 and vec4 are types defined elsewhere
UniformBuffer light<Variable<vec3>("location"), Variable<vec4>("rotation"), Variable<float>("intensity")>;

不幸的是,它没有编译,给了我错误“预期的'class'在'Variable'之前”(尽管将“ class”放进去只是产生了另一个错误,说它在'Variable之后期望了'>')。 即使查看有关可变参数模板的其他各种有趣的问题,我似乎也无法找到答案。 我要做什么的正确语法是什么?

看来您正在寻找专业化领域:

template<typename First, typename... Args>
class UniformBuffer;

template<typename First, typename... Args>
class UniformBuffer<Variable<First>,Variable<Args>...>
{
};

现场例子

您不能将Variable对象作为模板参数传递,因为无法在编译时推导它。

是一个解释,说明

不允许将类实例作为模板参数传递,因为模板参数需要编译时解析的东西(例如常量,函数名称,类型)。

不幸的是模板参数不能是字符串文字。

您可以做的是将这些实例传递到一个辅助函数中,从中可以根据这些实例的类型生成类似tuple的对象。

template <typename T>
struct Variable
{
    typedef T Type;
    const char *name;
    T val;
    constexpr Variable (const char *setName) : name(setName) {}
    operator T () const { return val; }
    operator T & () { return val; }
};

template <typename... V> UniformBuffer<V...> MakeUniformBuffer (V... args) {
    return UniformBuffer<V...>(args...);
}

{
    Variable<vec3> loc("location");
    Variable<vec4> rot("rotation");
    Variable<float> amp("intensity");
    auto ub = MakeUniformBuffer(loc, rot, amp);
...
}

MakeUniformBuffer将实例传递到UniformBuffer的构造函数中。 UniformBuffer必须解压缩变量模板参数。

template <typename... V> class UniformBuffer;

template <typename V>
struct UniformBuffer <V> {
    V val;
    UniformBuffer(V v) : val(v) {}
...
};

template <typename V, typename... VV>
struct UniformBuffer<V, VV...> {
    V val;
    UniformBuffer<VV...> ub;
    UniformBuffer(V v, VV... rest) : val(v), ub(rest...) {}
...
};

可以在UniformBuffer上实现set和get方法来按名称检索缓冲区元素。 下面是如何实现get方法的说明:

template <typename V>
struct UniformBuffer <V> {
...
    typename V::Type get (const Variable<typename V::Type> &v) {
        if (v.name != val.name) throw v.name;
        return val;
    }
    template <typename R> R get (const Variable<R> &v) {
        throw v.name;
        return R();
    }
};

template <typename V, typename... VV>
struct UniformBuffer<V, VV...> {
...
    typename V::Type get (const Variable<typename V::Type> &v) {
        if (v.name != val.name) return ub.get(v);
        return val;
    }
    template <typename R> R get (const Variable<R> &v) {
        return ub.get(v);
    }
};

{
...
    auto ub = MakeUniformBuffer(loc, rot, amp);
    auto r = ub.get(rot);
...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM