首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重载函数中的函数重载

重载函数中的函数重载
EN

Stack Overflow用户
提问于 2019-07-16 08:52:24
回答 5查看 84关注 0票数 1

我正在使用C++14 (而且对它非常陌生)。我有3个重载函数func,根据其父函数(func)调用另一个重载函数do_something

代码语言:javascript
复制
int func(int a) {
   bar(a);
   foo();
 }

int func(int a, float b) {
   bar(a);
   do_something(b);
   foo();
}

int func(int a, float b, char c) {
   bar(a);
   do_something(b, c);
   foo();
 }

我看到func中的功能几乎是相同的,只是调用了哪个版本的do_something。有什么方法可以使这个通用化并将所有的func合并在一起吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2019-07-16 09:04:53

首先,让func成为一个接受参数包的模板。int a参数、对bar的调用和对foo的调用总是存在的,所以这很简单。现在让我们为do_something添加一个占位符。

代码语言:javascript
复制
template <class ...Args>
int func(int a, Args&&... other)
{
   bar(a);
   // somehow call do_something and do the right thing
   foo();

   return 0;
}

您希望像前面一样实例化和调用上面的模板:

代码语言:javascript
复制
func(42);
func(42, 1.f);
func(42, 1.f, 'A');

现在,让我们来处理对do_something的调用。如果简单地将其添加到新的func模板的中间;

代码语言:javascript
复制
do_something(std::forward<Args>(other)...);

这拒绝为func(42)编译,即只有一个参数的情况。因此,我们需要一个特例来解决这个问题。在do_something的另一个间接方向上实现这一目标的方法之一

代码语言:javascript
复制
// No additional argument case, does nothing:
void do_something_wrapper() {}

// The other two cases    
template <class ...Args>
void do_something_wrapper(Args&&... args)
{
   do_something(std::forward<Args>(args)...);
}

现在,func函数模板的占位符应该是:

代码语言:javascript
复制
do_something_wrapper(std::forward<Args>(other)...);
票数 3
EN

Stack Overflow用户

发布于 2019-07-16 08:58:49

第一步是使用各种模板来获取您想要转发到do_something的部分。

代码语言:javascript
复制
template<class ... Args>
int func(int a, Args... args)
{
   bar(a);
   do_something(std::forward<Args>(args)...)
   foo();
}

但是现在你已经失去了func的论证类型。因此,如果这是一个问题,你将不得不找到一个方法来再次测试他们。

票数 2
EN

Stack Overflow用户

发布于 2019-07-16 09:08:17

虽然我可能会从generic_opto_guy本人那里得到答案,但他指出,您将失去接口中的类型,这是正确的。根据您的情况,您可能需要保留这个。

在这种情况下,您可以轻松地将其重新工作到类似于以下内容:

代码语言:javascript
复制
namespace details {

template<class ... Args>
int func_impl(int a, Args &&... args)
{
   bar(a);
   do_something(std::forward<Args>(args)...)
   foo();
}

}

int func(int a) { return details::func_impl(a); }

int func(int a, float b) { return details::func_impl(a, b); }

int func(int a, float b, char c) { return details::func_impl(a, b, c); }

注意,实现已经调整为使用完美转发。虽然在这种特殊情况下不需要,但它在转发将来可能遇到的情况时通常是有用的。

同样,除非您绝对需要向客户端代码提供一个清晰的接口,否则我将只使用第一个实现。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57053519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档