非类型模板参数

新手上路,请多包涵

我知道非类型模板参数应该是一个常量整数表达式。有人可以阐明为什么会这样吗?

 template <std::string temp>
void foo()
{
     // ...
}

 error C2993: 'std::string' : illegal type for non-type template parameter 'temp'.

我明白什么是常数积分表达式。在上面的代码段中不允许像 std::string 这样的非常量类型的原因是什么?

原文由 Mahesh 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 512
2 个回答

您不能这样做的原因是因为在编译时无法解析和替换非常量表达式。它们可能会在运行时发生变化,这需要在运行时生成新模板,这是不可能的,因为模板是一个编译时概念。

以下是标准允许的非类型模板参数(14.1 [temp.param] p4):

非类型模板参数应具有以下类型之一(可选 cv 限定):

  • 整数或枚举类型,
  • 指向对象的指针或指向函数的指针,
  • 对对象的左值引用或对函数的左值引用,
  • 指向成员的指针,
  • std::nullptr_t

原文由 Xeo 发布,翻译遵循 CC BY-SA 4.0 许可协议

您需要能够处理模板参数

template <std::string temp>
void f() {
 // ...
}

f<"foo">();
f<"foo">(); // same function?

现在,一个 impl 需要为 std::string 或任何其他任意用户定义的类提供一个唯一的字符序列,存储一个特定的值,其含义不为人所知执行。此外,任意类对象的值不能在编译时计算。

计划考虑允许文字类类型作为后 C++0x(见下文)的模板参数类型,这些类型由常量表达式初始化。这些可以通过根据数据成员的值递归地破坏数据成员来破坏(例如,对于基类,我们可以应用深度优先,从左到右的遍历)。但这绝对不适用于任意课程。


C++20 开始,我们现在可以使用 结构 类类型作为模板参数。简而言之,结构类必须有一个 constexpr 构造函数、析构函数,并且只有结构类型的成员和基类(如标量、数组或引用)。它们还必须只有公共的和非 mutable 基类和成员。如果模板是用转换为参数类型的常量表达式实例化的,这些规定允许编译器有意义地修改参数。

原文由 Johannes Schaub - litb 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题