返回 C++ 中函数的最后一个参数的通用包装器

发布于 2024-12-11 02:51:02 字数 565 浏览 1 评论 0原文

我们已经编写了一个大型库函数,其原型大多如下所示:

void my_fun(
  const in_class & in_param_1, 
  const in_class & in_param_2,
  const in_class & in_param_3,
  out_class & out_param);

是否有一种通用方法来包装这些函数,以便以下内容等效(假设 out_param 只写入 my_fun 中):

out_class my_out;
my_fun(my_in1,my_in2,my_in3,my_out);

以及

out_class my_out = generic_wrapper(&my_fun,my_in1,my_in2,my_in3);

如何编写这样一个 generic_wrapper?如果这是可能的,也可以编写它,以便输入参数的数量是可变的,这样我就可以将它与 my_fun2 一起使用,它可能需要 4 个 in_param_ 的?

We have written a large library functions whose prototypes mostly look like:

void my_fun(
  const in_class & in_param_1, 
  const in_class & in_param_2,
  const in_class & in_param_3,
  out_class & out_param);

Is there a generic way to wrap these functions so that the following is equivalent (assuming out_param is only written to in my_fun):

out_class my_out;
my_fun(my_in1,my_in2,my_in3,my_out);

and

out_class my_out = generic_wrapper(&my_fun,my_in1,my_in2,my_in3);

How could one write such a generic_wrapper? If this is possible it also possible to write it so that the number of input parameters is variable, so I could use it say with my_fun2 that perhaps takes 4 in_param_'s?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

翻了热茶 2024-12-18 02:51:02

考虑所有情况:

template<class T1, class Out>
Out generic_wrapper(void (*f)(const T1 &, Out &), const T1 & t1) { 
    Out out; 
    f(t1,out); 
    return out;
}

template<class T1, class T2, class Out>
Out generic_wrapper(void (*f)(const T1 &, const T2 &, Out &), const T1 & t1, const T1 & t2) { 
    Out out; 
    f(t1,t2,out); 
    return out;
}

// .....

template<class T1, class T2, class T3, class T4, class T5, class Out>
Out generic_wrapper(void (*f)(const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, Out &), const T1 & t1, const T1 & t2, const T3 & t3, const T4 & t4, const T5 & t5) { 
    Out out; 
    f(t1,t2,t3,t4,t5,out); 
    return out;
}

Consider all cases:

template<class T1, class Out>
Out generic_wrapper(void (*f)(const T1 &, Out &), const T1 & t1) { 
    Out out; 
    f(t1,out); 
    return out;
}

template<class T1, class T2, class Out>
Out generic_wrapper(void (*f)(const T1 &, const T2 &, Out &), const T1 & t1, const T1 & t2) { 
    Out out; 
    f(t1,t2,out); 
    return out;
}

// .....

template<class T1, class T2, class T3, class T4, class T5, class Out>
Out generic_wrapper(void (*f)(const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, Out &), const T1 & t1, const T1 & t2, const T3 & t3, const T4 & t4, const T5 & t5) { 
    Out out; 
    f(t1,t2,t3,t4,t5,out); 
    return out;
}
沉溺在你眼里的海 2024-12-18 02:51:02

使用 C++11 的可变参数模板,可以像这样实现包装器:

template <class Func, class ...Args>
typename last_argument_type<Func>::type wrapper(Func f, Args&& ...args)
{
    typename last_argument_type<Func>::type result;
    f(std::forward<Args>(args)..., result);
    return result;
}

并且我已将 last_argument_type 实现为:

//typedefs last type in T... as type
template <class ...T>
struct last_type;

template <class T, class ...U>
struct last_type<T, U...> { typedef typename last_type<U...>::type type; };

template <class T>
struct last_type<T> { typedef T type; };

//typedefs the type of the last argument of a function as type
//removes reference 
//e.g void(int, float, double&) -> type = double
template <class ...Args>
struct last_argument_type;

template <class Ret, class ...Args>
struct last_argument_type<Ret(*)(Args...)> {
    typedef typename std::remove_reference<typename last_type<Args...>::type>::type type;
};

完整示例位于 http://ideone.com/ef3zD

With variadic templates of C++11, it would be possible to implement the wrapper like this:

template <class Func, class ...Args>
typename last_argument_type<Func>::type wrapper(Func f, Args&& ...args)
{
    typename last_argument_type<Func>::type result;
    f(std::forward<Args>(args)..., result);
    return result;
}

and I've implemented last_argument_type as:

//typedefs last type in T... as type
template <class ...T>
struct last_type;

template <class T, class ...U>
struct last_type<T, U...> { typedef typename last_type<U...>::type type; };

template <class T>
struct last_type<T> { typedef T type; };

//typedefs the type of the last argument of a function as type
//removes reference 
//e.g void(int, float, double&) -> type = double
template <class ...Args>
struct last_argument_type;

template <class Ret, class ...Args>
struct last_argument_type<Ret(*)(Args...)> {
    typedef typename std::remove_reference<typename last_type<Args...>::type>::type type;
};

Full example at http://ideone.com/ef3zD

丶情人眼里出诗心の 2024-12-18 02:51:02

在 C++0x 中,我们还可以尝试使用可变参数模板:

template <class Out, class... Ins>
Out generic_wrapper(void (*fun)(const Ins&... , Out&), const Ins&... ins)
{
    Out out;
    fun(ins..., out);
    return out;
}

但我无法在不明确指定模板参数的情况下使用它(GCC 4.6.1):

int main()
{
    in_class in;
    out_class out1a = generic_wrapper(my_fun_1, in); // fails to compile...
    out_class out1b = generic_wrapper<out_class, in_class>(my_fun_1, in); // works...
    return 0;
}

In C++0x we could also try using variadic template:

template <class Out, class... Ins>
Out generic_wrapper(void (*fun)(const Ins&... , Out&), const Ins&... ins)
{
    Out out;
    fun(ins..., out);
    return out;
}

but I cannot use it w/o speficying template args explicitly (GCC 4.6.1):

int main()
{
    in_class in;
    out_class out1a = generic_wrapper(my_fun_1, in); // fails to compile...
    out_class out1b = generic_wrapper<out_class, in_class>(my_fun_1, in); // works...
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文