我们假设我们有以下代码:
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的指针。
答案 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
函数一起使用。 foo
,bar
和任何其他函数同时适用于指针和(左值和右值)引用。