【问题标题】:Type deduction for rvalues in templates模板中右值的类型推导
【发布时间】:2018-12-24 23:33:36
【问题描述】:

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

错误:无法绑定“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 字符*]

【问题讨论】:

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


    【解决方案1】:

    您的两个 sn-ps 之间的主要区别在于,第一个采用 const char*&amp;,第二个采用 const Key&amp;(又名 Key const&amp;),其中 Keyconst char*

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

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

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

    【讨论】:

    • 感谢您指出 const 关键字的正确位置。指针应该是 const ,因为这就是创建引用的对象。我对错误的理解是不正确的。这里取2个,请纠正或确认我的理解。它失败的原因是因为bchar *char const* 的隐式转换导致了一个右值,这会在分配给函数参数时导致错误。
    • @user2914100 甚至没有发现。这是真的,但没关系,因为create_buf() 无论如何都是右值
    • 你说得对,我在上一条评论中没有定义b。假设char * b = create_buf(); f_class.Firstfun(b);这将失败,因为从char *char const *的隐式转换,我猜......
    • @user2914100 我想是的 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2012-09-08
    相关资源
    最近更新 更多