[英]Template type deduction of const reference type
It is a bit confusing to me about how C++ 11 does template deduction when const references to a template parameter types are used.当使用对模板参数类型的 const 引用时,C++ 11 如何进行模板推导让我有点困惑。 Consider the following program:
考虑以下程序:
template <typename T> void test_func(const T &a){
(*a)++;
}
int main() {
// 1st case
int i = 1;
test_func(&i);
// 2nd case
const int* cPtr = &i;
test_func(cPtr);
}
My questions are:我的问题是:
int* const &a
(a top-level const);int* const &a
(顶级常量); but if we directly replace T with
int* , we get
const int* &a` (a low-level const) and compiler should have failed;T with
替换为 int* , we get
const int* &a` (一个低级 const)并且编译器应该会失败; how can we express a low-level const in a format of "const T &a";error: increment of read-only location `*(const int*)a;'
It seems like the second instantiated function inherits the low-level const as well;T
; T
的类型是什么;Your test_func()
receives a const reference to something.您的
test_func()
收到对某物的 const 引用。 In the first case, the something is the address of an integer, so the final type is "a reference which cannot be used to change its referent which is a pointer to an integer."在第一种情况下,某物是 integer 的地址,因此最终类型是“不能用于更改其所指对象的引用,它是指向 integer 的指针”。 This means you can use the pointer to the integer, including using it to change the integer, but you cannot change the value of the pointer (ie the address) to point to something else.
这意味着您可以使用指向 integer 的指针,包括使用它来更改 integer,但您不能将指针的值(即地址)更改为指向其他内容。
In the second case the final type is "a reference which cannot be used to change its referent which is a pointer to an integer and the pointer cannot be used to change the integer."在第二种情况下,最终类型是“不能用于更改其引用对象的引用,它是指向 integer 的指针,并且该指针不能用于更改 integer。” Therefore,
*a
is const int
which cannot be modified.因此,
*a
是不能修改的const int
。
if we directly replace
T
withint*
, we getconst int* &a
(a low-level const) and the compiler should have failed.如果我们直接将
T
替换为int*
,我们会得到const int* &a
(一个低级 const),编译器应该会失败。
Not really...并不真地...
The thing is, C++ (following C) has a somewhat convoluted syntax for declaring variables, "directly-replacing" doesn't mean "simple copy-pasting".问题是,C++(在 C 之后)声明变量的语法有些复杂,“直接替换”并不意味着“简单的复制粘贴”。 In your case, let's suppose you rewrite your declaration as
T const&
.在您的情况下,假设您将声明重写为
T const&
。 Now if you copy-paste you get:现在,如果你复制粘贴,你会得到:
void test2(int * const &a){
(*a)++;
}
which should compile just fine, and does.它应该编译得很好,并且可以。
what is the type of T?
T的类型是什么?
Let's check: Following an answer to this question: Print template typename at compile time让我们检查一下:在回答这个问题之后:在编译时打印模板类型名
we write:我们写:
template <typename T> void test_func(T const &a){
bool x = T::nothing;
(*a)++;
}
int main() {
int i = 1;
// 2nd case
const int* cPtr = &i;
test_func(cPtr);
}
and when we run this program , we get:当我们运行这个程序时,我们得到:
source>: In instantiation of 'void test_func(const T&) [with T = const int*]':
<source>:10:19: required from here
<source>:2:17: error: 'nothing' is not a member of 'const int*'
2 | bool x = T::nothing;
| ^~~~~~~
so, T
is const int*
for this case.因此,对于这种情况,
T
是const int*
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.