C++ 在Bjarne的示例中,为什么可以将常量限定对象传递给非常量参数?

C++ 在Bjarne的示例中,为什么可以将常量限定对象传递给非常量参数?,c++,c++11,C++,C++11,我正在读比亚恩的书,下面是一个例子: template <class T, class A1> std::shared_ptr<T> factory(A1& a1) { return std::shared_ptr<T>(new T(a1)); } 模板 std::共享的ptr 工厂(A1和A1) { 返回std::shared_ptr(新T(a1)); } 这样好多了。如果将常量限定类型传递给 工厂,常数将被推导到模板参数中(A1用于 然

我正在读比亚恩的书,下面是一个例子:

template <class T, class A1>
std::shared_ptr<T>
factory(A1& a1)
{
    return std::shared_ptr<T>(new T(a1));
}
模板
std::共享的ptr
工厂(A1和A1)
{
返回std::shared_ptr(新T(a1));
}
这样好多了。如果将常量限定类型传递给 工厂,常数将被推导到模板参数中(A1用于 然后正确地转发给T的构造函数


我不明白
::factory()
如何接受常量引用。Bjarne只是声明常量将被推导到模板参数中。这到底意味着什么

如果传入类型为
const X
的左值,则
A1
将被推断为
const X
,您将得到如下函数

std::shared_ptr<T> factory(const X& a1) { ... }
std::共享ptr工厂(const X&a1){…}

模板类型扣减通常发生在三种情况下:

  • 参数类型是引用或指针,但不是通用的
  • 参考参数类型是一种通用参考参数类型
  • 既不是引用也不是指针
您的案例属于非通用参考参数推断。规则将是: 若表达式是引用,则忽略该引用 模式将表达式的类型与参数类型匹配,以确定类型T

例如:

template<typename T>
void factory(T& param);      // param is a reference

int x = 42;        // int
const int cx = x;  // copy of int
const int& rx = x; // ref to const view of int

factory(x);   // 1, T = int, param's type = int&
factory(cx);  // 2, T = const int, param's type = const int&
factory(rx);  // 3, T = const int, param's type = const int&
模板
无效工厂(T¶m);//param是一个引用
int x=42;//int
常数int cx=x;//int的副本
常数int&rx=x;//参考int的常量视图
工厂(x);//1,T=int,参数类型=int&
工厂(cx);//2,T=const int,参数类型=const int&
工厂(rx);//3,T=const int,参数类型=const int&
现在您可以看到,当您传入
const X时,它与案例2匹配,如果传入
const X&
时,它与案例3匹配

注意:std::shared_ptr是您的示例中的噪声,我将其删除以演示类型推断