模板中右值的类型推导

时间:2018-12-24 23:33:37

标签: c++ c++11 templates rvalue-reference

需要一些帮助来了解右值引用的类型推导。非模板版本因以下错误而失败,我理解原因。

  

错误:无法绑定“ const char *&”类型的非常量左值引用   到'const char *'类型的右值

在C ++ 11中,如果我将函数void Firstfun(const Key& key)更改为void Firstfun(const Key&& key),则它可以编译,但是模板化版本可以使用左值引用参数正常工作。

对于有模板的版本,我认为编译器必须已生成带有右值引用的函数,因此使用__PRETTY_FUNCTION__对其进行了检查,但在PRETTY_FUNCTION的输出中未看到它。

我确实遇到了this的讨论,其中@Anirban在这些行中提到了一些东西。

  

对于wrapper(A());,类型参数T仍将推导为A,   并且参数u的类型为A &&,称为右值引用   到A。

所以这是我的问题:

  1. 编译器如何处理模板化版本以使其接受右值?
  2. 针对非模板版本的修补程序void Firstfun(const Key&& key)是否有效且可以接受?

非模板版本

#include <iostream>

namespace somens {

class Firstclass {
public:

    void Firstfun(const char*& key) {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }
};

class Secondclass {
    Firstclass f_class;

    char* create_buf(){
        char * buf = new char[10]; //buf will be freed elsewhere.
        return buf;
    }

public:
    void Secondfun (){
        f_class.Firstfun(create_buf());
    }

};
}

int main () {
  somens::Secondclass s_class;
  s_class.Secondfun();

}

非模板版本的输出

  

错误:无法绑定“ const char *&”类型的非常量左值引用   到'const char *'类型的右值

模板化版本

#include <iostream>

namespace somens {
template<typename Key>
class Firstclass {
public:

    void Firstfun(const Key&  key) {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }
};

class Secondclass {
    Firstclass<const char*> f_class;

    char* create_buf(){
        char * buf = new char[10]; //buf will be freed elsewhere.
        return buf;
    }

public:
    void Secondfun (){
        f_class.Firstfun(create_buf());
    }

};
}

int main () {
  somens::Secondclass s_class;
  s_class.Secondfun();

}

模板版本的输出

  

void somens :: Firstclass :: Firstfun(const Key&)[with Key = const   字符*]

1 个答案:

答案 0 :(得分:1)

两个代码段之间的主要区别在于,第一个代码段占用const char*&,第二个代码段占用const Key&(又名Key const&),其中Key是{{1} }。

至关重要的是,在后一种情况下,这会为您提供一个const char*,该{像对const char* const&的任何其他左值引用一样)可以绑定到临时目录。

请记住,const中的const是无关紧要的,因为它描述的是指针对象,而不是指针。

您不需要模板。您只需编写const char*就可以观察到这一点。