C++ 重载函数以接受模板指针变量
在main函数中调用push方法时使用它。但是,即使主函数中的参数是指针,它仍然使用函数C++ 重载函数以接受模板指针变量,c++,templates,pointers,overloading,C++,Templates,Pointers,Overloading,在main函数中调用push方法时使用它。但是,即使主函数中的参数是指针,它仍然使用函数void Push(const DATA\u TYPE&newValue) 它不应该使用另一个,因为它是接受指针的那个吗?如果存在指针变量,如何更改第二个函数中的参数以覆盖该函数 template<typename DATA_TYPE> void Push(const DATA_TYPE& newValue) { //do stuff } template<typen
void Push(const DATA\u 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
}
模板
无效推送(常量数据类型和新值)
{
//做事
}
模板
无效推送(常量数据类型*新值)
{
//做事
}
我已经测试了这个程序
#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;
}
你的问题在于康斯特内斯 问题是,当您使用非常量对象指针调用
Push(p)
时,p*p
第一个版本在设置数据类型=p*
时正好工作,给出了Push(const p*&)
的函数签名。相比之下,第二个版本的DATA_TYPE=P
要求在类型签名中添加const
,以获得Push(const P*)
。这意味着将选择第一个版本而不是第二个版本,因为它是完全匹配的
下面是一个例子来说明发生了什么:
下面是一个例子:
#include <iostream>
class Foo
{
public:
template<typename DT>
void Push(const DT& newValue)
{
std::cout<<"In const DT& version"<<std::endl;
}
template<typename DT>
void Push(const DT *newValue)
{
std::cout<<"In const DT* version"<<std::endl;
}
};
int main()
{
Foo f;
int i=7;
// Since i is not const we pickup the wrong version
f.Push( i ); // const DT& ( DT = int )
f.Push( &i ); // const DT& ( DT = int* )
// Here's using a const pointer to show it does the right things
const int * const_i_ptr = &i;
f.Push( const_i_ptr ); // const DT* ( DT = int );
// Now using a const object everything behaves as expected
const int i_const = 7;
f.Push( i_const ); // const DT& ( DT = int );
f.Push( &i_const ); // const DT* (DT = int );
}
#包括
福班
{
公众:
模板
无效推送(常数DT和新值)
{
std::cout这是因为const DATA\u TYPE&newValue
几乎可以匹配任何东西,在您的情况下,它匹配指针const DATA\u TYPE*&newValue
。尝试使用std::remove\u pointer
-从我的头顶上我会写:
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
}
这正如预期的那样工作,它不会强制调用方使用适当的常量,尽管我承认它没有我以前的解决方案那么吸引人;)这里的区别是模板无效推送(t*)
是一个模板,其中无效推送(const DATA_TYPE*newValue)
不是。我看不出这与问题有什么关系。缺少的常量&x
是一个右值,不能绑定到非常量
参考。您可能已经澄清,这意味着参考版本提供了精确匹配,但指针版本仍然需要从非常量
进行类型转换到const
指针,所以参考版本更匹配。@Keith我同意,希望我现在已经充分说明了这一点。似乎你不能用那种方式进行参数类型推断:看看所有的内容都解释得很好。
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
}
#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;
}