引用与指针指定

Reference vs pointer specilization

本文关键字:指针 引用      更新时间:2023-10-16

让我们假设我们有以下代码:

template<class T>
void foo(T& v)
{
  std::cout<<v[0]<<std::endl;
}
template<class T>
void foo(T* v)
{
  std::cout<<v[0]<<std::endl;
}
void main(void)
{
  std::vector<int> vec(5,1);
  foo(vec);
  int* cvec(new int[5]);
  cvec[0]=1;
  foo(cvec);
}

有没有一种方法可以避免重写第二个函数的主体,只需调用第一个函数(可能进行某种类型的强制转换或类似的操作)?

更新也许我的main有点误导,但我想用C样式数组调用foo,而不是用指向std::vector的指针。

"有没有一种方法可以避免重写第二个函数的主体,只需调用第一个函数(可能进行某种类型的强制转换或类似的操作)?"

你可以写

template<class T>
void foo(T& v) {
    foo(&v);
}

也将指针传递给CCD_ 1
或者反过来绕过

template<class T>
void foo(T* v) {
    foo(*v);
}

通过解引用CCD_ 2。

我认为你给自己制造了一个问题。。。如果你想要一个可以在数组上操作的模板函数foo,你只需要使用基本模板:

template <typename T>
void foo(T & t) {
   t[0];
}
int main() {
   int array[0] = { 123 };
   foo(array);
   std::vector<int> v{ 123 };
   foo(v);
}

这里的关键是,如果函数参数是按值的,则类型数组的参数的推导类型将衰减为指针,但如果参数是引用,则不会衰减。

考虑以下代码:

template<class T>
void foo(T& v)
{
    std::cout << v[0] << std::endl;
}
template<class T>
void bar(T* v)
{
    foo(*v);
}
void main(void)
{
    std::vector<int> vec(5,1);
    foo(vec);
    bar(&(vec[0]));
}

请记住,指针只是保存地址的变量,因此由于foo需要一个地址,因此简单地将指针值传递给它是完全合法的,而指针值实际上是一个地址。

希望能有所帮助!

如注释中所述,如果您进一步使用助手来访问参数,您也可以使用未指定的基本模板:

#include <iostream>
template<typename T> T&& call(T&& t) {return std::forward<T>(t);}
template<typename T> T& call(T* t) {return *t;}
template<typename T>
void foo(T&& t)
{
    std::cout<<"foo: "<<call(std::forward<T>(t))<<std::endl;
}
template<typename T>
void bar(T&& t)
{
    std::cout<<"bar: "<<call(std::forward<T>(t))<<std::endl;
}
int main()
{
    int a=1;
    int *b=new int(2);
    foo(a);
    foo(b);
    foo(3);
    bar(a);
    bar(b);
    // your code goes here
    return 0;
}

可以注意到,这种方法很有帮助,因为不需要重新专门化每个类模板,而是始终将基本模板与曾经实现的call函数一起使用。foobar和任何其他函数将同时对指针和(左值和右值)引用起作用。