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 &]