如何正确编写内联模板函数,将指针向前移动一个偏移量,并将指针返回到另一种类型? 问 如何将一个指针类型指向一个对象类型,以将指针指向另一个指针,由代码>模板到*OffStPtR(从*p,sisixt off)< /> >在C++中没有模板参数? 描述
众所周知,当增加或减少指针时,差值是指针指向的对象的大小。 为了向指针添加特定偏移量,我认为有两种方式:如何正确编写内联模板函数,将指针向前移动一个偏移量,并将指针返回到另一种类型? 问 如何将一个指针类型指向一个对象类型,以将指针指向另一个指针,由代码>模板到*OffStPtR(从*p,sisixt off)< /> >在C++中没有模板参数? 描述,c++,templates,C++,Templates,众所周知,当增加或减少指针时,差值是指针指向的对象的大小。 为了向指针添加特定偏移量,我认为有两种方式: 转换为指向char->指针算术->强制转换或强制转换为指向其他类型的指针 强制转换为intptr\t,它有足够的位来容纳指针->整数算术->强制转换或强制转换为指向其他类型的指针 在C++中,不允许直接将指针分配给对象类型转换为指针的对象类型(例如,代码> int *pINT1=原始)。 因此,我希望模板能对我有所帮助,但似乎无法从assignment表达式中的左值类型正确推断作为返回类型的
char
->指针算术->强制转换或强制转换为指向其他类型的指针int*pint3=offsetptr(pchar,sizeof(raw.a))代码>没有模板参数
顺便说一句,如何捕获模板参数推断/替换的结果?就像gcc无法推断模板参数“To”一样,它将打印错误:调用“convert(double&)”时没有匹配的函数。
工具书类
返回类型不参与模板参数推导:。为什么?这不是一个好的设计C++或编译器,因为类型安全,所以要求我们显式执行类型强制转换。但是,通过编写函数,我对此有了明确的认识。返回类型的可能重复项不参与模板参数推导:。为什么?这不是一个好的设计C++或编译器,因为类型安全,所以要求我们显式执行类型强制转换。但是,通过编写一个函数,我对此有了一个清晰的认识
template<typename To, typename From> To convert(From f);
void g(double d)
{
int i = convert<int>(d); // calls convert<int, double>(double)
char c = convert<char>(d); // calls convert<char, double>(double)
int(*ptr)(float) = convert; // instantiates convert<int, float>(float)
}
// int i = 6; offsetptr(i, 16) == 22
// int *i = offsetptr(pchar, 16); *i == 22
template<typename DstPointeeType, typename SrcPointeeType>
inline static DstPointeeType* offsetptr(SrcPointeeType *p, size_t off) {
cout << "p = " << p << ", *p = " << *p << endl;
return reinterpret_cast<DstPointeeType*>(reinterpret_cast<char*>(p) + off);
}
template<typename DstType, typename SrcType>
inline static DstType differby(SrcType src, size_t off) {
return reinterpret_cast<DstType>(reinterpret_cast<intptr_t>(src) + off);
}
template<typename DstType, typename SrcType>
inline static DstType udifferby(SrcType src, size_t off) {
return reinterpret_cast<DstType>(reinterpret_cast<uintptr_t>(src) + off);
}
template<> int* offsetptr<int, char>(char *p, size_t off) {
cout << "p = " << p << ", *p = " << *p << endl;
return reinterpret_cast<int*>(p + off);
}
//template<typename InType, typename OutType> static const OutType* offsetptr(const InType *p,
// size_t off) {
// return (const OutType*) ((const char*) p + off);
//}
template<typename T> inline static void moveptr(T **pp, unsigned int stride = sizeof(T)) {
*pp = (T*) ((char*) *pp + stride);
// p = (void*)((char*)p + stride);
}
int main() {
// your code goes here
union{
struct{
char a[sizeof(int)];
int b;
int c;
};
char chars[];
}raw = {{"ss", 22}};
char *pchar = raw.chars;
int *pint1 = &raw.c, *pint2 = &raw.c, *pint3 = &raw.c, *pint4 = &raw.c;
// a long code, or maybe define a macro
pint1 = (int*) ((char*) pchar + sizeof(raw.a));
pint2 = (int*) ((intptr_t) pchar + sizeof(raw.a));
// expect a unified way
pint3 = differby<int*, char*>(pchar, sizeof(raw.a));
pint3 = offsetptr<int>(pchar, sizeof(raw.a));
pint4 = (int*)pchar;
moveptr(&pint4, sizeof(raw.a));
cout << *pint1 << ", " << *pint2 << ", " << *pint3 << ", " << *pint4 << endl;
return 0;
}