【问题标题】:How can const be applied to template argument types outside of the parameter list in C++?如何将 const 应用于 C++ 中参数列表之外的模板参数类型?
【发布时间】:2019-09-03 09:56:37
【问题描述】:

我正在研究 C++ 模板,但我一直在思考 const 和作为模板函数参数的类型之间的交互。具体来说,我正在考虑在模板参数列表之外应用 const 时如何与模板类型交互。

我已经尝试在 C++ Primer 5th ed (Lippman) 和 C++11 标准草案中寻找这种交互,但是在这种情况下 const 要么没有明确提及,要么(在标准的情况下)相当复杂它的描述(我对 C++ 还是有点陌生​​)。

这是我的问题的代码示例:

template<typename T>
const T & constify(T & t) {
    return t;
}

...

int* i = 0x12345678; 
constify(i);

我对返回类型有两种不同的期望:

  1. 推导出的返回类型是const (int *) &amp;,即后面会应用const,所以我们不能修改int指针,但我们可以修改它指向的东西。
  2. 推导出来的返回类型是const int * &amp;,即所有的声明符和限定符都是一次性应用的,而不是像1中那样。这里,我们不能再修改整数指向的int,但我们可以修改指针本身.

对我来说,第一个更有意义,因为它背后有一个自然的“类替换”规则,类似于 typedef。但我的问题是;其中哪一项(如果有)是正确的,为什么?

【问题讨论】:

  • #1 是正确的,因为这就是语言规范所说的。 Tint*,指向 int 的指针。所以const Tint* const - 指向int 的常量指针,而不是指向常量int 的指针。 const 不会跳到类型的中间。

标签: c++ templates constants


【解决方案1】:

const 一致 位置在类型的右侧。一些声明,如变量,也允许将 const 放在左侧,但其他一些声明,如成员函数定义,只允许将 const 放在右侧。

如果您始终将const 放在/应用在右侧,它会帮助您以正确的方式思考它。这就是许多 boost 库将const 放在右侧的原因。

constify 苹果const 在右边,因此,它将Tint* 变成int* const - 一个指向非常量int 的常量指针。并应用右侧的引用:int* const&amp;

【讨论】:

    【解决方案2】:

    第一个是正确的,返回类型为int * const &amp;,即const指针对非const int的引用;不是const int * &amp;,即指向constint的非常量指针的引用。

    constT 本身上是合格的,当 T 是指针时,const T 将是 const 指针,但不是指向 const 指针的指针。

    【讨论】:

      【解决方案3】:

      模板类型替换不是文本的,所以不要根据文本类型定义来考虑它们。

      在您的示例中,T 被推断为int * - 我们称之为intptr。您正在对它进行const 引用,因此返回值变为const intptr&amp;。也就是说,指针本身不能通过这个引用来修改,但是它指向的值是可以修改的。

      最后但并非最不重要的一点是,您可以在提出问题之前轻松验证您的假设 :)

      【讨论】:

      • 这个答案正是我想要的,谢谢!所以本质上,一个类型名可以被认为是它如何与声明符和限定符交互的类型别名? (我很抱歉没有事先验证)
      猜你喜欢
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 2019-03-29
      • 2011-12-16
      • 1970-01-01
      • 2020-04-12
      • 2012-10-09
      • 1970-01-01
      相关资源
      最近更新 更多