在模板上下文中通过引用传递的参数的"const"限定符的位置

The position of 'const' qualifier of a parameter which is passed by reference in template context

本文关键字:参数 const 位置 上下文 引用      更新时间:2023-10-16

考虑以下两个原型:

template<class T>
void whatever1(const T& something);
template<class T>
void whatever2(T const& something);

它们都是相同的。但是,如果T不是通常的类型,而是指针类型呢?例如,让T Somewhere*然后whatever1whatever2会有不同的解释:

// nonconst pointer (passed by reference) to const object
void whatever1(const Somewhere*& something);
// const pointer (passed by reference) to nonconst object
void whatever2(Somewhere* const& something);

在这种情况下,我可以推断以下属性:

1 whatever1

a) 可以修改内部something,这些更改会传播到外部;

b) something指向的对象不能被修改。

2 whatever2

a) 不能修改内部something,因此外部安全;

b)something指向的对象可以修改。

通常const&一起使用,以避免在传递参数时复制,并同时保护此参数不被修改。那么就这种哲学而言,只有whatever2发挥其作用。但是,如果我希望something指向的对象也是不可修改的,那么两个都不合适!那会是什么呢?也许这个笑话:

template<class T>
void whatever3(const T const& something);

除了这种混乱之外,有些人使用whatever1风格,而另一些人则使用whatever2风格。根据经验,在创建泛型类和方法时应使用哪一个?

请注意,如果我们开始考虑Somewhere** T事情会变得更加混乱。

你的假设是错误的。当T = U *时,T const &const T &都是U * const &,仅此而已。类似地,const TT const都是U * const的,当T = const W时,T *W const *const W *。(当然,这都受引用折叠规则的约束,因此假设UW都不是引用类型)。

当模板实例化时,将 T 替换为 Somewhere* 不是文本模板 - 因此在这两种情况下,const 都将应用于指针,而不是它指向的东西。

不能以这种方式将const限定符注入命名类型。 举个简单的例子,如果您有:

typedef int* P;
const P x;

那么xint* const 型,而不是 const int* 型。 const应用于整个P类型,而不仅仅是P类型的一部分。 这同样适用于模板类型参数。

如果要将const限定符注入到类型中,可以毫不费力地执行此操作,例如,通过使用 remove_pointeradd_const 等类型特征。

它们都是相同的。但是,如果T不是通常的类型,而是指针类型呢?例如,让我们T Somewhere*然后whatever1whatever2会有不同的解释:

// nonconst pointer (passed by reference) to const object
void whatever1(const Somewhere*& something);
// const pointer (passed by reference) to nonconst object
void whatever2(Somewhere* const& something);

不,实际上它不会void whatever1(const Somewhere*& something);,它会在无效的类似C++的代码中void whatever1(const (Somewhere*)& something);。写它C++方法是你的whatever2,但它们的意思是一样的。