【问题标题】:Template argument for non-type parameter must be an expression非类型参数的模板参数必须是表达式
【发布时间】:2016-06-17 11:32:42
【问题描述】:

为什么下面的代码错了?

template <typename T, int N>
struct Vector {
    T data[N];
};

struct Dynamic {
};

template <typename T>
struct Vector<T, Dynamic> {
    T* data;
};

我尝试使用Vector&lt;int, Dynamic&gt; obj; 实例化代码,但没有成功

错误:非类型模板参数的模板参数必须是表达式

为什么?我正在传递一个类型,我认为这是一个有效的模板特化。

如果标有Dynamic,我如何使用两个模板,一个请求 N,一个不请求 N?

【问题讨论】:

  • 主模板需要int,但您在专业化中提供了Dynamic,所以这是无效的。
  • 错误信息没有准确地说明问题所在吗? Dynamic 不是表达式,而是类型名称。这不是int 的值。
  • @KerrekSB 好的,但是为什么 this 不工作呢?这是另一个模板,完全不相关
  • @Dean 这两个模板并非不相关,因为第二个模板是第一个模板的特化。
  • @Dean:同样的问题。别介意部分特化定义了一个新模板,但是您试图根据一个没有意义的模板实例化来定义它。

标签: c++ templates


【解决方案1】:
template <typename T, int N>
struct Vector {
    T data[N];
};

在您的主模板类中,T 必须是 type、(int, short, class-type, etc)...Nnon-type,并且必须是计算结果为 int 类型的表达式(一个数字)。

struct Dynamic {
};

template <typename T>
struct Vector<T, Dynamic> {
    T* data;
};

Dynamic 是一种类型。不是主模板中指定的int


根据您的主要模板类,您只能使用int 专门化Vector 的第二个模板参数。例如。

template <typename T>
struct Vector<T, 1> {
    T* data;
};

template <typename T>
struct Vector<T, 35> {
    T* data;
};

template <typename T>
struct Vector<T, constExpressionThatReturnsAnInt> {
    T* data;
};

...etc

【讨论】:

    【解决方案2】:

    您不能将Dynamic 用于特化Vector,因为Dynamic 是一个,而您的主模板需要一个int。你想要的可能是这样的:

    #include <limits>
    
    constexpr size_t Dynamic = std::numeric_limits<size_t>::max();
    
    template <typename T, size_t N>
    struct Vector {
        T data[N];
    };
    
    template <typename T>
    struct Vector<T, Dynamic> {
        T* data;
    };
    
    Vector<int, 10> static_array;
    Vector<int, Dynamic> dynamic_array;
    

    这里的Dynamic 是正确类型的constexpr (size_t),因此您可以专门化您的模板。您根本无法创建大小为 std::numeric_limits&lt;size_t&gt;::max() 的静态数组(这应该不是问题)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 2021-02-04
      • 2011-12-10
      • 2017-03-23
      相关资源
      最近更新 更多