在main函数中调用push方法时使用。但是,即使main函数中的参数是指针,它仍然使用函数void Push(const DATA_TYPE& newValue)
。
不应该使用另一个,因为那是接受指针的人吗?如果存在指针变量,如何更改第二个函数中的参数以覆盖该参数?
template<typename DATA_TYPE>
void Push(const DATA_TYPE& newValue)
{
//do stuff
}
template<typename DATA_TYPE>
void Push(const DATA_TYPE *newValue)
{
//do stuff
}
答案 0 :(得分:4)
你的问题在于constness。
问题在于,当您使用非const对象指针Push(p)
调用P * p
时,第一个版本在设置DATA_TYPE = P*
时正好工作,给出{{1}的函数签名1}}。相比之下,DATA_TYPE = Push( const P* & )
的第二个版本需要在类型签名中添加P
才能获得const
。这意味着选择第一个版本而不是第二个版本,因为它是精确匹配。
这是一个澄清正在发生的事情的例子:
以下是一个例子:
Push( const P* )
答案 1 :(得分:0)
我测试了这个程序
#include <iostream>
template <typename T>
void push(T&)
{
std::cout << "By ref" << std::endl;
}
template <typename T>
void push(T*)
{
std::cout << "By ptr" << std::endl;
}
int main()
{
int x = 0;
push(x);
push(&x);
return 0;
}
输出
By ref
By ptr
答案 2 :(得分:0)
这是因为const DATA_TYPE& newValue
几乎可以匹配任何东西,在你的情况下它匹配作为指针const DATA_TYPE*& newValue
的引用。尝试使用std::remove_pointer
described here - 从我的头脑中我会写:
template<typename DATA_TYPE>
void Push(const typename std::remove_pointer<DATA_TYPE>::type& newValue)
{
//do stuff
}
template<typename DATA_TYPE>
void Push(const DATA_TYPE *newValue)
{
//do stuff
}
但是,编写匹配const T&
模板以及其他模板重载的模板通常会导致const T&
抓取每个调用,因此您应该避免以这种方式执行操作。
编辑:
我之前的代码不正确,它必须更复杂一些:
#include <iostream>
#include <type_traits>
template<typename DATA_TYPE, bool is_pointer>
struct helper;
template<typename DATA_TYPE>
struct helper<DATA_TYPE, true>{
static void f(const typename std::remove_pointer<DATA_TYPE>::type*){
std::cout << "Pointer" << std::endl;
}
};
template<typename DATA_TYPE>
struct helper<DATA_TYPE, false>{
static void f(const DATA_TYPE&){
std::cout << "Non-pointer" << std::endl;
}
};
template<typename DATA_TYPE>
void Push(const DATA_TYPE& newValue)
{
helper<DATA_TYPE, std::is_pointer<DATA_TYPE>::value >::f(newValue);
}
int main()
{
int i=0;
Push(i);
Push(&i);
return 0;
}
这可以按预期工作,并且它不会强制调用者使用适当的常量,尽管我承认它不像我以前的解决方案那样迷人;)