模板中右值的类型推导

Type deduction for rvalues in templates

请求帮助理解右值引用的类型推导。非模板版本失败,出现以下错误,我明白原因。

error: cannot bind non-const lvalue reference of type 'const char*&' to an rvalue of type 'const char*'

对于 C++11,如果我将函数 void Firstfun(const Key& key) 更改为 void Firstfun(const Key&& key),那么它会编译,但是模板化版本可以很好地使用左值引用参数。

至于模板化版本,我认为编译器一定生成了带有右值引用的函数,所以用 __PRETTY_FUNCTION__ 检查了它,但在 PRETTY_FUNCTION.[=21= 的输出中没有看到它]

我确实遇到了 讨论,其中@Anirban 提到了这些内容。

For wrapper(A());, the type parameter T would still be deduced as A, and the parameter u would be of type A&&, called an rvalue reference to 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();

}

非模板版本的输出

error: cannot bind non-const lvalue reference of type 'const char*&' to an rvalue of type '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 char*]

两个片段之间的主要区别在于第一个片段采用 const char*&,第二个片段采用 const Key&(又名 Key const&),其中 Keyconst char*.

至关重要的是,在后一种情况下,这给了你一个 const char* const& ,它(像任何其他对 const 的左值引用一样)可以绑定到一个临时的。

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

您不需要模板。您只需编写 using Key = const char*.

就可以观察到这一点