c++ - 模板选择 const 引用而不是 const 指针

标签 c++ c++11 templates

考虑以下几点:

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 xconst 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/

相关文章:

c++ - 进程名称比较

c++ - put_time() 忽略时区偏移量的转换说明符 'z'

c++ - 这是制作迭代器的可接受方式吗?

c++ - 任何返回类型的可变函数包装器

C++。当类T需要类型A模板参数时,如何为类A定义类型T的模板参数?

c++ - 在 C++ 中编译时间类型确定

c++ - 为什么 Qt Stylesheet "Foo:hover * {"总是适用?

c++ - 在 C++ 中使用 C 特性是不好的做法吗?

c++ - 列表迭代器不兼容断言失败

c++ - 将右值引用分配给左值引用