考虑以下几点:
template <class T> void Foo(const T* x) {
std::cout << "I am the pointer overload" << std::endl;
}
template <class T> void Foo(const T& x) {
std::cout << "I am the reference overload" << std::endl;
}
鉴于上述情况,我希望以下调用指针重载:
int* x;
Foo(x);
但事实并非如此。这对我来说似乎很奇怪,因为 const T*
可以清楚地绑定(bind)到非 const T
就像 const T&
一样,但是指针变体似乎“更合适”。
对于我的应用程序,我希望调用指针变体。我可以通过额外的特化来完成这项工作:
template <class T> void Foo(T* x) {
const T* const_x = x;
Foo(const_x);
}
但这感觉是错误的和不必要的。有没有更好的办法?我不明白什么(除了标准的 x.y.z 部分说是这样)?
最佳答案
您在想:如果我的参数不是常量(或者如果参数是常量),那么指针将是完美匹配。 这是正确的。 我所拥有的是 const
。因此,只需将 const
添加到上述场景中,我也应该得到指针重载。这也是正确的。既然你清楚地得到了引用过载,那怎么可能呢?好吧,代码与您的想法不符。以下是符合您的思路的代码,并且确实会选择指针重载:
template <class T> void Foo(T* const x);
template <class T> void Foo(T const &x);
注意const
的位置。我添加了 const
作为顶级限定符。虽然 T const &x
与您拥有的 const T& x
等价,但 T* const x
与 const T* 不同x
.
让我们看看这种情况下的重载解决方案:
fun | T | parameter | argument
-----------------------------------------+------+--------------+-----------
template <class T> void Foo(T* const x) | int | int* const | int*
template <class T> void Foo(T const &x) | int* | int* const & | int*
让我们看看你的版本的重载:
fun | T | parameter | argument
-----------------------------------------+------+--------------+-----------
template <class T> void Foo(const T* x) | int | const int* | int*
template <class T> void Foo(T const &x) | int* | int* const & | int*
正如您在第一个版本中看到的那样,最好只添加顶级 const 并选择指针重载。不需要指针转换。
在第二种情况下,指针重载需要将指针从 pointer to mutable
转换为 pointer to const
。这些是不同类型的指针。但是对于第二次重载,不需要指针转换。只需添加一个顶级 const
。
简而言之,这是我不用去就可以解释的最好的内容这就是标准的 x.y.z 部分所说的
关于c++ - 模板选择 const 引用而不是 const 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47988388/