简体   繁体   English

const引用类型的模板类型推导

[英]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:我的问题是:

  • For the first case, it is compiled fine;对于第一种情况,它编译得很好; so it seems like the instantiated template function parameter is int* const &a (a top-level const);所以看起来实例化的模板 function 参数是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";我们如何以“const T &a”的格式表达一个低级的 const; I am confused what is the real type of the parameter and what is the type of T;我很困惑参数的真实类型是什么,T的类型是什么;
  • For the second case, compilation fails with an对于第二种情况,编译失败并出现
    error: increment of read-only location `*(const int*)a;'
    It seems like the second instantiated function inherits the low-level const as well;似乎第二个实例化的 function 也继承了低级 const; then what is the type of parameter;那么参数的类型是什么; what is the type of 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

First case第一个案例

if we directly replace T with int* , we get const 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.它应该编译得很好,并且可以。

Second case第二种情况

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.因此,对于这种情况, Tconst int*

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM