模板类型推断时,常引用的constness要不要保留

窗外蓝天 2016-10-16 03:53:08
Effective Modern C++的Item 1, Case3:ParamType is Neigher a Pointer nor a Reference(影印版p14底)里面写到
引用
As we've seen, for parameters that are references-to or pointers-to-const, the constness of expr is preserved during type deduction.

但是根据前文的说明(先去引用,再去constness),我觉得"parameters that are references-to"应该不会保留constness啊。
//比如
template<typename T>
void tFunc (T param)
{
...
}

int x = 5 ;
const int &crX = 5 ;

tFunc (crx) ;//应该是tFunc<int> (int)而不是tFunc<const int> (const int)吧

是我理解错了吗,还是书上写错了,求指点。
...全文
168 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
窗外蓝天 2016-10-17
  • 打赏
  • 举报
回复
引用 15 楼 pengzhixi 的回复:
去看下前面的case 1你就知道了
我想你和9楼的意思是一样的,对于void tFunc (T ¶m)这种情况,constness确实是保留了的。
pengzhixi 2016-10-17
  • 打赏
  • 举报
回复
引用 14 楼 q408384053 的回复:
[quote=引用 13 楼 pengzhixi 的回复:] As we've seen, for parameters that are references-to or pointers-to-const, the constness of expr is preserved during type deduction. 这里的parameters 对于 template<typename T> void tFunc (T param) { ... } 来说 是指param是references-to or pointers-to-const
恩,但是param是references-to的时候,没有保留constness啊[/quote]去看下前面的case 1你就知道了
窗外蓝天 2016-10-16
  • 打赏
  • 举报
回复
引用 13 楼 pengzhixi 的回复:
As we've seen, for parameters that are references-to or pointers-to-const, the constness of expr is preserved during type deduction. 这里的parameters 对于 template<typename T> void tFunc (T param) { ... } 来说 是指param是references-to or pointers-to-const
恩,但是param是references-to的时候,没有保留constness啊
pengzhixi 2016-10-16
  • 打赏
  • 举报
回复
As we've seen, for parameters that are references-to or pointers-to-const, the constness of expr is preserved during type deduction. 这里的parameters 对于 template<typename T> void tFunc (T param) { ... } 来说 是指param是references-to or pointers-to-const
窗外蓝天 2016-10-16
  • 打赏
  • 举报
回复
引用 10 楼 pengzhixi 的回复:
你理解没问题,书上也没说错啊。
我想他这句话的意思是可以void tFunc (crX)推断为void tFunc<const int> (const int),但是这个推断出void tFunc<int>(int)有矛盾啊
窗外蓝天 2016-10-16
  • 打赏
  • 举报
回复
引用 9 楼 fefe82 的回复:
[quote=引用 6 楼 q408384053 的回复:] [quote=引用 4 楼 fefe82 的回复:] 没有看你的上下文,不过,在标准里,parameter 是形参,argument 是实参。这里你的 parameter type 是 T ,不是引用,也就无所谓 parameters that are references-to 了。
恩,我在vs2015里面试了确实是将T和parameter type推断为int,但是这不和我引用的那句话(the constness of expr preserved during type deduction.)有矛盾吗?[/quote] 这句话是有条件的,for parameters that are references-to or pointers-to-const 。你的 parameter 是 T param ,既不是引用,也不是指针,条件并不满足,不适用这句话。[/quote] 我知道你的意思了,你觉得那句话的references-to是适用void tFunc (T ¶m)这种情况是吧? 有可能,但是这句话是出现在void tFunc (T param)下的,而且后面的pointers-to-const也是对应的void tFunc (T param)这种情况(而不是void tFunc (const T *param)),所以我感到奇怪。
pengzhixi 2016-10-16
  • 打赏
  • 举报
回复
你理解没问题,书上也没说错啊。
fefe82 2016-10-16
  • 打赏
  • 举报
回复
引用 6 楼 q408384053 的回复:
[quote=引用 4 楼 fefe82 的回复:] 没有看你的上下文,不过,在标准里,parameter 是形参,argument 是实参。这里你的 parameter type 是 T ,不是引用,也就无所谓 parameters that are references-to 了。
恩,我在vs2015里面试了确实是将T和parameter type推断为int,但是这不和我引用的那句话(the constness of expr preserved during type deduction.)有矛盾吗?[/quote] 这句话是有条件的,for parameters that are references-to or pointers-to-const 。你的 parameter 是 T param ,既不是引用,也不是指针,条件并不满足,不适用这句话。
窗外蓝天 2016-10-16
  • 打赏
  • 举报
回复
引用 7 楼 q408384053 的回复:
[quote=引用 5 楼 paschen 的回复:] Const Pointers 与 Pointers to Const 是不同的 char* const 表示指针本身是常量(Const Pointers) const char* 表示的是指针指向的是常量,指针本身不是常量(Pointers to Const ) 书上用的是pointers-to-const,也就是后者,同理引用
这个我了解。 [/quote]

int x = 5 ;
const int *pX = &x ;
const int *const cpX = &x ;
tFunc (pX) ; //调用tFunc<const int *> (const int *)
tFunc (cpX) ; //调用tFunc<const int *> (const int *)
窗外蓝天 2016-10-16
  • 打赏
  • 举报
回复
引用 5 楼 paschen 的回复:
Const Pointers 与 Pointers to Const 是不同的 char* const 表示指针本身是常量(Const Pointers) const char* 表示的是指针指向的是常量,指针本身不是常量(Pointers to Const ) 书上用的是pointers-to-const,也就是后者,同理引用
这个我了解。

int x = 5 ;
const int *pX = &x ;
tFunc (pX) ; //调用tFunc<const int *> (const int *)
窗外蓝天 2016-10-16
  • 打赏
  • 举报
回复
引用 4 楼 fefe82 的回复:
根据 5 Expressions 5 If an expression initially has the type “reference to T” (8.3.2, 8.5.3), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression. tFunc (crx) 里 crx 的类型将被调整为 const int 。 根据 14.8.2.1 Deducing template arguments from a function call 2 If P is not a reference type: (2.1) — If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of A for type deduction; otherwise, (2.2) — If A is a function type, the pointer type produced by the function-to-pointer standard conversion (4.3) is used in place of A for type deduction; otherwise, (2.3) — If A is a cv-qualified type, the top level cv-qualifiers of A’s type are ignored for type deduction. 但 P (这里是 T ) 不是引用是,A (这里是 const int ) 的最外层的 cv-qualifier 会被忽略。 所以最终调用的是 tFunc<int> 。 ============================================================ 没有看你的上下文,不过,在标准里,parameter 是形参,argument 是实参。这里你的 parameter type 是 T ,不是引用,也就无所谓 parameters that are references-to 了。
恩,我在vs2015里面试了确实是将T和parameter type推断为int,但是这不和我引用的那句话(the constness of expr preserved during type deduction.)有矛盾吗?
paschen 版主 2016-10-16
  • 打赏
  • 举报
回复
Const Pointers 与 Pointers to Const 是不同的 char* const 表示指针本身是常量(Const Pointers) const char* 表示的是指针指向的是常量,指针本身不是常量(Pointers to Const ) 书上用的是pointers-to-const,也就是后者,同理引用
fefe82 2016-10-16
  • 打赏
  • 举报
回复
根据 5 Expressions 5 If an expression initially has the type “reference to T” (8.3.2, 8.5.3), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression. tFunc (crx) 里 crx 的类型将被调整为 const int 。 根据 14.8.2.1 Deducing template arguments from a function call 2 If P is not a reference type: (2.1) — If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of A for type deduction; otherwise, (2.2) — If A is a function type, the pointer type produced by the function-to-pointer standard conversion (4.3) is used in place of A for type deduction; otherwise, (2.3) — If A is a cv-qualified type, the top level cv-qualifiers of A’s type are ignored for type deduction. 但 P (这里是 T ) 不是引用是,A (这里是 const int ) 的最外层的 cv-qualifier 会被忽略。 所以最终调用的是 tFunc<int> 。 ============================================================ 没有看你的上下文,不过,在标准里,parameter 是形参,argument 是实参。这里你的 parameter type 是 T ,不是引用,也就无所谓 parameters that are references-to 了。
窗外蓝天 2016-10-16
  • 打赏
  • 举报
回复
引用 2 楼 q408384053 的回复:
感谢,但你没有直接回答我的问题,我所描述的情况对应着你代码中第3,4行,照你说的就是不包含cv属性,所以你是觉得书上的描述有问题,这是意思吗?
打错字了,是这意思吗?
窗外蓝天 2016-10-16
  • 打赏
  • 举报
回复
感谢,但你没有直接回答我的问题,我所描述的情况对应着你代码中第3,4行,照你说的就是不包含cv属性,所以你是觉得书上的描述有问题,这是意思吗?
ID870177103 2016-10-16
  • 打赏
  • 举报
回复
//没有指定T时候,编译器会根据实参来推导T的类型
//T被推导成实参的类型,不包含cv属性
template <class T>
void func1 (T t) {}
//T &被推导成实参的左值引用类型,和实参的cv属性一致
template <class T>
void func2 (T &t) {}
//T &&被推导成实参的引用类型,和实参的cv属性和引用属性一致
template <class T>
void func3 (T &&t) {}
//编译器无法自动推导T的类型
template <class T>
void func4 (typename std::remove_cv<T>::type t) {}

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧