引用vs指针特化

时间:2014-10-15 16:45:03

标签: c++ templates pointers reference

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

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);
}

有没有办法避免重写第二个函数的主体,只需调用第一个函数(也许做某种类型的转换或类似的东西)?

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

4 个答案:

答案 0 :(得分:1)

  

“有没有办法避免重写第二个函数的主体,只需调用第一个函数(也许做某种演员或类似的东西)?”

你可以写

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

也将指针传递给T& 或者反过来

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

取消引用T*

答案 1 :(得分:0)

考虑以下代码:

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需要一个地址,因此只需将指针值传递给它就完全合法,这实际上是一个地址。

希望有所帮助!

答案 2 :(得分:0)

我认为你为自己创造了一个问题...如果你想要的是一个可以在数组上运行的模板函数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);
}

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

答案 3 :(得分:0)

如评论中所述,如果您进一步使用帮助程序访问参数,您还可以使用未指定的基本模板:

#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和任何其他函数同时适用于指针和(左值和右值)引用。