通过宏创建模板专业化

Creating template specializations via a macro

本文关键字:专业化 建模 创建      更新时间:2023-10-16

我正在尝试创建一个助手方法createTypedArray,它"知道"每个元素要分配多少字节。即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

通常您希望使用sizeof(ElementType),例如:

auto buffer = AllocateSomeBuffer(numberOfElements * sizeof(ElementType));

不过,您不是直接使用ElementType,而是使用数组类型的一些表示。不用担心,我们只需要从您的T中取出ElementType

遗憾的是,这些类似乎没有T::value_typeT::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_typeelement_size是多余的,而前者更通用,所以我选择了那个)。