我正在尝试创建一个帮助方法createTypedArray
,并且#34;知道&#34;每个元素要分配多少字节。也就是说,createTypedArray<Float32Array>(size)
而非createTypedArray<Float32Array, 4>(size)
。
这是我提出的最佳方法。有更好的方法吗?这是一个我不喜欢的虚拟主要模板,至少。
#define TYPED_ARRAY_P(T, bytesPerElement) \
template <> \
Local<T> createTypedArray<T>(size_t size) { \
size_t byteLength = size * bytesPerElement; \
Local<ArrayBuffer> buffer = ArrayBuffer::New(Isolate::GetCurrent(), byteLength); \
Local<T> result = T::New(buffer, 0, size); \
return result; \
}
// Dummy
template <typename T>
Local<T> createTypedArray(size_t s) {
return void;
}
TYPED_ARRAY_P(Uint8Array, 1);
TYPED_ARRAY_P(Uint16Array, 2);
TYPED_ARRAY_P(Uint32Array, 4);
#undef TYPED_ARRAY_P
答案 0 :(得分:2)
通常您想使用sizeof(ElementType)
,例如:
auto buffer = AllocateSomeBuffer(numberOfElements * sizeof(ElementType));
但是,您不是直接使用ElementType
,而是使用数组类型的某种表示形式。不用担心,我们只需要从ElementType
中获取T
。
可悲的是,这些类似乎没有像T::value_type
或T::element_size
或其他任何东西。但是,我们仍然希望在T
和它的元素大小之间有一个“保证”的映射,而不是每次都抽出一些魔术常量。
这类问题的通常解决方案是“类型特征”。这些是类特化,它们为我们提供了有关类型的计算信息。在我们的例子中,我们想要这样的东西:
template <typename T>
struct V8TypeTraits; // no generic case (e.g. can't ask for V8 traits about int)
template <>
struct V8TypeTraits<Uint8Array> {
typedef std::uint8_t value_type;
};
// etc.
现在我们可以获得ElementType
:
template <typename T>
Local<T> createTypedArray(size_t elementCount) {
const size_t byteLength =
elementCount * sizeof(typename V8TypeTraits<T>::value_type);
// etc.
return result;
}
显然你不必做value_type
,你可以把static constexpr element_size = /* whatever */;
放在你的特质中并使用:
const size_t byteLength =
elementCount * V8TypeTraits<T>::element_size;
但是映射到value_type
是返回C ++域的最短路径(例如,同时拥有value_type
和element_size
将是多余的,前者更通用,所以我选那个)。