如何将结构类型作为参数传递给函数?

时间:2013-03-06 06:03:05

标签: c++ templates

我正在尝试向函数添加参数,我需要将新参数作为结构类型。

以下是我要更改的功能,来自dyld_decache.cpp

void prepare_patch_objc_methods(uint32_t method_vmaddr, uint32_t override_vmaddr);

我这样改了:

template <typename T>
void prepare_patch_objc_methods(typename T::type, uint32_t list_vmaddr, uint32_t override_vmaddr);

prepare_patch_objc_methods的实施过程中,我将所有出现的method_t更改为T,并且编译得很好。

method_t结构的定义如下:

struct method_t {
    uint32_t name;
    uint32_t types;
    uint32_t imp;
};

现在,如何在调用此函数时传递结构类型?

我试图这样做

this->prepare_patch_objc_methods(method_t, class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));

但是我收到以下错误:'method_t' does not refer to a value

2 个答案:

答案 0 :(得分:4)

看起来你不需要将你的struct类型的对象传递给函数(你只需要传递一个类型本身),所以正确的函数声明将是

template <typename T>
void prepare_patch_objc_methods(uint32_t list_vmaddr, uint32_t override_vmaddr);

现在将结构类型传递给你称之为函数的函数

this->prepare_patch_objc_methods<method_t>(class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));

如果你确实需要传递参数类型的对象,你可以这样做

template <typename T>
    void prepare_patch_objc_methods(const T &object, uint32_t list_vmaddr, uint32_t override_vmaddr);

然后你这样称呼它

method_t obj;
this->prepare_patch_objc_methods<method_t>(obj, class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));

或者只是喜欢这个

this->prepare_patch_objc_methods(obj, class_data->baseMethods, class_obj->data + offsetof(class_ro_t, baseMethods));

在这里,您不一定需要明确指定类型,因为编译器可以从您传递的对象中推断出它。

答案 1 :(得分:2)

您需要传递该类型的实际对象,而不是类型本身,作为参数:

method_t m;

prepare_patch_objc_methods(m, class_data->baseMethods, /* ... */);

编辑:如果不清楚:您不能将类型(例如method_t)作为普通参数传递 - 您只能将其作为模板参数传递。对于函数模板,模板参数通常由编译器根据您为该参数传递的类型自动推导出来,因此给出:

template <class T>
void f(T x) {}

编译器会发现,如果您传递(例如)1作为参数,则T将为此实例化int。如果您改为通过1.0,则会发现该T double为{}}。

如果你真的想(比如想要将值转换为T的类型,而不是选择T作为传递的任何类型),你可以为函数模板指定一个模板参数,就像你可以为类做的那样模板。例如,f<double>(1)将为double实例化f,即使您传递的值是int。因此,在传递给函数之前,int将被提升为double。