在可变参数模板中初始化静态数组 class
Initialize static array in variadic template class
我有一个可变参数模板 class "InterleavedAttribute",现在我想要一些关于模板中类型的运行时信息 ("AttributeTypeInfo")。我想在模板 class ("attributeInfo") 中填充一个静态 const 数组,然后在运行时使用索引访问该数组,例如 object.typeInfo(2),但我无法弄清楚如何。这是我拥有的:
#include <iostream>
template <typename TYPE> struct GLTypeInfo;
template <>
struct GLTypeInfo<char> { static constexpr unsigned int glType = 0; };
template <>
struct GLTypeInfo<int> { static constexpr unsigned int glType = 1; };
template <>
struct GLTypeInfo<float> { static constexpr unsigned int glType = 2; };
//---------------------------------------------------------------------------
struct AttributeTypeInfo
{
unsigned int nrOfComponents;
unsigned int glType;
unsigned int bytesPerComponent;
unsigned int bytesPerAttribute;
constexpr AttributeTypeInfo(unsigned int _nrOfComponents, unsigned int _glType, unsigned int _bytesPerComponent, unsigned int _bytesPerAttribute)
: nrOfComponents(_nrOfComponents), glType(_glType), bytesPerComponent(_bytesPerComponent), bytesPerAttribute(_bytesPerAttribute)
{}
};
template <typename T>
struct TypeInfoFactory
{
static unsigned int constexpr extent = std::is_array<T>::value ? std::extent<T>::value : 1;
using type = typename std::conditional<std::is_array<T>::value, typename std::remove_extent<T>::type, T>::type;
static constexpr AttributeTypeInfo typeInfo = AttributeTypeInfo(extent, GLTypeInfo<type>::glType, sizeof(type), sizeof(type) * extent);
};
//---------------------------------------------------------------------------
template <typename TYPE, typename ...P> struct InterleavedAttribute
{
static constexpr unsigned int nrOfAttributes = sizeof...(P)+1;
//static constexpr AttributeTypeInfo attributeInfo[sizeof...(P)+1] = { ??? }; // <-- How do I fill this...
TYPE data;
InterleavedAttribute<P...> next;
InterleavedAttribute() {}
InterleavedAttribute(const TYPE & value, const P &... p) : data(value), next(p...) {}
//static constexpr AttributeTypeInfo typeInfo(unsigned int index) { return attributeInfo[index]; } // ...so I can call this later?
};
template <typename TYPE> struct InterleavedAttribute<TYPE>
{
static constexpr unsigned int nrOfAttributes = 1;
static constexpr AttributeTypeInfo attributeInfo[1] = { TypeInfoFactory<TYPE>::typeInfo };
TYPE data;
InterleavedAttribute() {}
InterleavedAttribute(const TYPE & value) : data(value) {}
static constexpr AttributeTypeInfo typeInfo(unsigned int index) { return attributeInfo[0]; }
};
int main() {
InterleavedAttribute<int> ia1(5);
std::cout << "Numer of attributes: " << ia1.nrOfAttributes << std::endl;
std::cout << "Attribute 0, glType: " << ia1.typeInfo(0).glType << std::endl;
InterleavedAttribute<float, int, char> ia3(1.2, 3, 'a');
std::cout << "Numer of attributes: " << ia3.nrOfAttributes << std::endl;
//std::cout << "Attribute 0, glType: " << ia3.typeInfo(0).glType << std::endl; <-- Trying to get type information here
}
代码在 Coliru here。
我找到了 this 答案,而且很接近,但我仍然无法真正弄清楚如何得到我想要的...
您可以使用 std::tuple
执行以下操作:
template <typename ...Ts> struct InterleavedAttribute
{
static constexpr unsigned int nrOfAttributes = sizeof...(Ts);
static constexpr AttributeTypeInfo attributeInfo[sizeof...(Ts)] = {
TypeInfoFactory<Ts>::typeInfo...
};
std::tuple<Ts...> data;
InterleavedAttribute() {}
InterleavedAttribute(const Ts&... args) : data(args...) {}
static constexpr AttributeTypeInfo typeInfo(unsigned int index) {
return attributeInfo[index];
}
template <unsigned int I>
auto attribute() -> decltype(std::get<I>(data)) { return std::get<I>(data); }
template <unsigned int I>
auto attribute() const -> decltype(std::get<I>(data)) { return std::get<I>(data); }
};
// odr-used, so definition required for linker.
template <typename ...Ts>
constexpr AttributeTypeInfo InterleavedAttribute<Ts...>::attributeInfo[sizeof...(Ts)];
我有一个可变参数模板 class "InterleavedAttribute",现在我想要一些关于模板中类型的运行时信息 ("AttributeTypeInfo")。我想在模板 class ("attributeInfo") 中填充一个静态 const 数组,然后在运行时使用索引访问该数组,例如 object.typeInfo(2),但我无法弄清楚如何。这是我拥有的:
#include <iostream>
template <typename TYPE> struct GLTypeInfo;
template <>
struct GLTypeInfo<char> { static constexpr unsigned int glType = 0; };
template <>
struct GLTypeInfo<int> { static constexpr unsigned int glType = 1; };
template <>
struct GLTypeInfo<float> { static constexpr unsigned int glType = 2; };
//---------------------------------------------------------------------------
struct AttributeTypeInfo
{
unsigned int nrOfComponents;
unsigned int glType;
unsigned int bytesPerComponent;
unsigned int bytesPerAttribute;
constexpr AttributeTypeInfo(unsigned int _nrOfComponents, unsigned int _glType, unsigned int _bytesPerComponent, unsigned int _bytesPerAttribute)
: nrOfComponents(_nrOfComponents), glType(_glType), bytesPerComponent(_bytesPerComponent), bytesPerAttribute(_bytesPerAttribute)
{}
};
template <typename T>
struct TypeInfoFactory
{
static unsigned int constexpr extent = std::is_array<T>::value ? std::extent<T>::value : 1;
using type = typename std::conditional<std::is_array<T>::value, typename std::remove_extent<T>::type, T>::type;
static constexpr AttributeTypeInfo typeInfo = AttributeTypeInfo(extent, GLTypeInfo<type>::glType, sizeof(type), sizeof(type) * extent);
};
//---------------------------------------------------------------------------
template <typename TYPE, typename ...P> struct InterleavedAttribute
{
static constexpr unsigned int nrOfAttributes = sizeof...(P)+1;
//static constexpr AttributeTypeInfo attributeInfo[sizeof...(P)+1] = { ??? }; // <-- How do I fill this...
TYPE data;
InterleavedAttribute<P...> next;
InterleavedAttribute() {}
InterleavedAttribute(const TYPE & value, const P &... p) : data(value), next(p...) {}
//static constexpr AttributeTypeInfo typeInfo(unsigned int index) { return attributeInfo[index]; } // ...so I can call this later?
};
template <typename TYPE> struct InterleavedAttribute<TYPE>
{
static constexpr unsigned int nrOfAttributes = 1;
static constexpr AttributeTypeInfo attributeInfo[1] = { TypeInfoFactory<TYPE>::typeInfo };
TYPE data;
InterleavedAttribute() {}
InterleavedAttribute(const TYPE & value) : data(value) {}
static constexpr AttributeTypeInfo typeInfo(unsigned int index) { return attributeInfo[0]; }
};
int main() {
InterleavedAttribute<int> ia1(5);
std::cout << "Numer of attributes: " << ia1.nrOfAttributes << std::endl;
std::cout << "Attribute 0, glType: " << ia1.typeInfo(0).glType << std::endl;
InterleavedAttribute<float, int, char> ia3(1.2, 3, 'a');
std::cout << "Numer of attributes: " << ia3.nrOfAttributes << std::endl;
//std::cout << "Attribute 0, glType: " << ia3.typeInfo(0).glType << std::endl; <-- Trying to get type information here
}
代码在 Coliru here。 我找到了 this 答案,而且很接近,但我仍然无法真正弄清楚如何得到我想要的...
您可以使用 std::tuple
执行以下操作:
template <typename ...Ts> struct InterleavedAttribute
{
static constexpr unsigned int nrOfAttributes = sizeof...(Ts);
static constexpr AttributeTypeInfo attributeInfo[sizeof...(Ts)] = {
TypeInfoFactory<Ts>::typeInfo...
};
std::tuple<Ts...> data;
InterleavedAttribute() {}
InterleavedAttribute(const Ts&... args) : data(args...) {}
static constexpr AttributeTypeInfo typeInfo(unsigned int index) {
return attributeInfo[index];
}
template <unsigned int I>
auto attribute() -> decltype(std::get<I>(data)) { return std::get<I>(data); }
template <unsigned int I>
auto attribute() const -> decltype(std::get<I>(data)) { return std::get<I>(data); }
};
// odr-used, so definition required for linker.
template <typename ...Ts>
constexpr AttributeTypeInfo InterleavedAttribute<Ts...>::attributeInfo[sizeof...(Ts)];