2

我一直在使用带有原始类型参数的模板来研究像素格式和画布系统,即:

enum class PIXEL_FORMAT : char {
    PALETTE,
    RGB,
    RGBA
};

template<unsigned int bit_depth, PIXEL_FORMAT fmt> struct Pixel {};

//specializations for 8-bit, 16-bit, etc. RGB/RGBA formats

这些都工作得很好,但是当我尝试创建一个 Layer 结构时:

template< template<unsigned int depth, PIXEL_FORMAT fmt> class PixelType > struct Layer {
using pixel = PixelType<depth, fmt>;
pixel** pixels;

我得到的错误是:

F:\Personal Projects (Java or Other)\C_C++\Independent\GUI Apps\FreeArt\Canvas.h|7|error: 'depth' was not declared in this scope
F:\Personal Projects (Java or Other)\C_C++\Independent\GUI Apps\FreeArt\Canvas.h|7|error: 'fmt' was not declared in this scope
F:\Personal Projects (Java or Other)\C_C++\Independent\GUI Apps\FreeArt\Canvas.h|7|error: template argument 1 is invalid
F:\Personal Projects (Java or Other)\C_C++\Independent\GUI Apps\FreeArt\Canvas.h|7|error: template argument 2 is invalid

所以显然我不理解使用原始类型作为参数的嵌套模板的工作方式。我一直在寻找类似的问题,但似乎找不到任何关于使用原始类型而不是常规模板参数(typename T等)的内容。

我希望这可以用于使用原始类型参数的模板的其他类型,例如可能的

template<template<unsigned int bit_depth, double samp_per_sec> class Sound> struct SoundEffect {};
4

1 回答 1

3

如果要在图层中使用单个像素类型,则需要:

template < typename PixelType > struct Layer {
   ...
};

using RGBA8Layer = Layer < Pixel<8, RGBA> >;

如果您需要从inside 访问bit_depth和访问,请在其中一个或单独的“特征”模板中定义静态 const 成员。formatLayerPixel

您尝试使用的构造称为“模板模板参数”。当您可能有许多具有相同签名的模板时需要它们:

template <unsigned int bit_depth, PIXEL_FORMAT fmt> struct Pixel {};
template <unsigned int bit_depth, PIXEL_FORMAT fmt> struct FancyPixel {};
template <unsigned int bit_depth, PIXEL_FORMAT fmt> struct FastPixel {};
template <unsigned int bit_depth, PIXEL_FORMAT fmt> struct PackedPixel {};

并且您想将它们中的任何一个与 一起使用Layer并且您想从 layer 内部选择深度和格式,那么您可以使用它:

template< template<unsigned int, PIXEL_FORMAT> class PixelType > 
struct Layer {
    using MyNormalPixel = PixelType<8, RGB>;
    using MyHighDefinitionPixel = PixelType<16, RGBA>;
};

using FancyLayer = Layer<FancyPixel>;
using PackedLayer = Layer<PackedPixel>;

注意参数名称是如何PixelType被省略的——它们根本不能在代码中使用。它们唯一有用的是文档。这种情况类似于函数参数的情况:

// signature off the top of my head
double integrate (double func(double), 
                  double from, double to, double epsilon, double step);

实际上,模板本质上是类型域中的函数,“模板模板参数”类似于func上面的“函数函数参数”。

于 2013-08-29T18:47:02.193 回答