1

考虑以下两个原型:

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

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

它们都是相同的。然而,如果T不是通常的类型,而是指针类型呢?例如, let be TthenSomewhere*会有不同的解释: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变得更加混乱。

4

4 回答 4

3

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

于 2012-04-09T22:06:00.440 回答
3

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

typedef int* P;
const P x;

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

如果你想const在类型中注入一个限定符,你可以毫不费力地做到这一点,例如通过使用像remove_pointerand之类的类型特征add_const

于 2012-04-09T22:06:47.400 回答
3

你的假设是错误的。When T = U *, thenT const &const T &are both U * const &,仅此而已。类似地,const TandT const都是U * const,而当T = const W,thenT *W const *or const W *。(当然,这都受引用折叠规则的约束,因此假设既不是引用类型U也不W是引用类型)。

于 2012-04-09T22:08:39.753 回答
1

它们都是相同的。然而,如果T不是通常的类型,而是指针类型呢?例如, let be TthenSomewhere*会有不同的解释: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);,它会void whatever1(const (Somewhere*)& something);在无效的类 C++ 代码中。编写它的 C++ 方式是你的whatever2,但它们的意思是一样的。

于 2012-04-09T22:08:29.193 回答