Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;模板右值向量与常量引用向量_C++_Templates_C++11_Constructor - Fatal编程技术网

C++ C++;模板右值向量与常量引用向量

C++ C++;模板右值向量与常量引用向量,c++,templates,c++11,constructor,C++,Templates,C++11,Constructor,代码 #include <iostream> using namespace std; #define PF cout << __PRETTY_FUNCTION__ << endl; class berlp { public: berlp() { } void p() { } }; template <typename T> class derp { public: derp() = default;

代码

#include <iostream>

using namespace std;

#define PF         cout << __PRETTY_FUNCTION__ << endl;

class berlp {
public:
    berlp() { }
    void p() { }
};

template <typename T>
class derp {
public:
    derp() = default;

    derp(const T & a) : mem(a) {
        a.p();
        mem.p();

        PF
    }

    template <typename U>
    derp(U && a) : mem(std::forward<U>(a)) {
        PF
    }

    T       mem;
};

int main(int argc, const char * argv[])
{
    berlp                   one;
    derp<berlp &>           f(one);     // problems with this list below
    derp<const berlp &>     h(one);     // problem with this follows

    return 0;
}
#包括
使用名称空间std;

#定义PF cout这里有很多问题:

  • 为什么
    derp(one)
    使用第一个构造函数

    构造函数的声明是
    derp(T const&)
    ,它变成
    derp(berlp&const&)
    ,并被折叠成
    derp(berlp&)
    ,因为没有
    const
    引用或引用引用。这在8.3.2[dcl.ref]第6段中说明:

    如果typedef(7.1.3)、类型模板参数(14.3.1)或decltype说明符(7.1.6.2)表示引用类型T的类型TR,则尝试创建类型“对cv TR的左值引用”将创建类型“对T的左值引用”,而尝试创建类型“对cv TR的右值引用”将创建类型TR

    显然,将
    berlp&
    传递给使用
    berlp&
    的构造函数是完全匹配的,模板构造函数做得再好不过了。因此,选择了非模板构造函数

  • 为什么用
    berlp
    调用
    derp(one)

    这里没有什么真正令人惊讶的:
    mem
    属于
    berlp&
    类型,并用
    berlp&
    初始化,因此非
    const
    成员都能按预期工作

  • 当使用
    derp
    并传递
    berlp&
    时,模板构造函数是完美匹配的,显然是被选中的。类型为
    berlp const&
    的成员变量刚刚用
    berlp&
    初始化,该变量隐式转换为
    berlp const&
    。这也不足为奇


  • 我想你只是对引用崩溃规则有点困惑。将
    常量
    放在错误的位置也无济于事:将其放在正确的位置实际上可以消除大部分混淆,并且是将
    常量
    放在正确位置的一部分。

    这里确实有多个问题:

  • 为什么
    derp(one)
    使用第一个构造函数

    构造函数的声明是
    derp(T const&)
    ,它变成
    derp(berlp&const&)
    ,并被折叠成
    derp(berlp&)
    ,因为没有
    const
    引用或引用引用。这在8.3.2[dcl.ref]第6段中说明:

    如果typedef(7.1.3)、类型模板参数(14.3.1)或decltype说明符(7.1.6.2)表示引用类型T的类型TR,则尝试创建类型“对cv TR的左值引用”将创建类型“对T的左值引用”,而尝试创建类型“对cv TR的右值引用”将创建类型TR

    显然,将
    berlp&
    传递给使用
    berlp&
    的构造函数是完全匹配的,模板构造函数做得再好不过了。因此,选择了非模板构造函数

  • 为什么用
    berlp
    调用
    derp(one)

    这里没有什么真正令人惊讶的:
    mem
    属于
    berlp&
    类型,并用
    berlp&
    初始化,因此非
    const
    成员都能按预期工作

  • 当使用
    derp
    并传递
    berlp&
    时,模板构造函数是完美匹配的,显然是被选中的。类型为
    berlp const&
    的成员变量刚刚用
    berlp&
    初始化,该变量隐式转换为
    berlp const&
    。这也不足为奇


  • 我想你只是对引用崩溃规则有点困惑。将
    const
    放在错误的位置也无济于事:将其放在正确的位置实际上可以消除大部分混淆,并且是将
    const
    放在正确位置的一部分。

    一些关于通用引用和重载的阅读:还有这个问题:一些关于通用引用和重载的阅读:还有这个问题:我再也不会把const放在左边了!这就把一切都清理干净了。谢谢我再也不会把康斯特放在左边了!这就把一切都清理干净了。谢谢
    derp<berlp &>::derp(const T &) [T = berlp &]
    derp<const berlp &>::derp(U &&) [T = const berlp &, U = berlp &]