Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 重载函数中的函数重载_C++_Templates_C++14_Variadic Templates - Fatal编程技术网

C++ 重载函数中的函数重载

C++ 重载函数中的函数重载,c++,templates,c++14,variadic-templates,C++,Templates,C++14,Variadic Templates,我正在使用C++14,对它还很陌生。我有3个重载函数func,其中另一个重载函数dou_something根据其父函数func被调用 我看到func中的功能几乎相同,只是调用了哪个版本的do_something。有没有什么方法可以将此通用化并将所有func组合在一起?第一步是使用可变模板来获取您要转发的零件以执行以下操作: 但是现在您已经丢失了func的参数类型。因此,如果这是一个问题,您必须找到一种方法再次测试它们。第一步是使用可变模板来获取您想要转发的部分,以便执行以下操作: 但是现在您已经

我正在使用C++14,对它还很陌生。我有3个重载函数func,其中另一个重载函数dou_something根据其父函数func被调用


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

第一步是使用可变模板来获取您要转发的零件以执行以下操作:


但是现在您已经丢失了func的参数类型。因此,如果这是一个问题,您必须找到一种方法再次测试它们。

第一步是使用可变模板来获取您想要转发的部分,以便执行以下操作:

但是现在您已经丢失了func的参数类型。因此,如果这是一个问题,您必须找到一种方法来再次测试它们。

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

现在,让我们来解决做点什么的问题。如果您只是将它添加到新的FUNC模板的中间;p>
do_something(std::forward<Args>(other)...);
现在,func函数模板中的占位符应该是:

do_something_wrapper(std::forward<Args>(other)...);
首先,将func设置为接受参数包的模板。int a参数、对bar的调用和对foo的调用总是存在的,所以这很简单。现在让我们为do_某事添加一个占位符

现在,让我们来解决做点什么的问题。如果您只是将它添加到新的FUNC模板的中间;p>
do_something(std::forward<Args>(other)...);
现在,func函数模板中的占位符应该是:

do_something_wrapper(std::forward<Args>(other)...);

虽然我可能会同意generic_opto_guy自己的答案,但他正确地指出,您将丢失界面中的类型。根据您的情况,您可能希望保留此功能

在这种情况下,您可以轻松地将其返工为类似于以下内容的内容:

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); }
请注意,该实现已调整为使用。虽然在这种特殊情况下不需要,但它在转发将来可能遇到的情况时通常很有用


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

尽管我可能会同意generic_opto_guy本人的答案,但他正确地指出,您将丢失接口中的类型。根据您的情况,您可能希望保留此功能

在这种情况下,您可以轻松地将其返工为类似于以下内容的内容:

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); }
请注意,该实现已调整为使用。虽然在这种特殊情况下不需要,但它在转发将来可能遇到的情况时通常很有用


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

其他答案是对问题的通用答案,但如果您有一些可用的c备用值,您可以编写如下内容:

int func(int a) {
   func(a, 0.0,'\001');
}

int func(int a, float b, char c = '\002') {
   bar(a);
   switch (c) {
   case '\001':
      break;              // func(a)
   case '\002':
      do_something(b):    // func(a, b)
      break;
   default:
      do_something(b, c); // func(a, b, c)
      break;
   }
   foo();
}

根据应用程序的不同,这可能会更简单。

其他答案是对所问问题的良好通用答案,但如果您有一些可用的c备用值,您可以编写如下内容:

int func(int a) {
   func(a, 0.0,'\001');
}

int func(int a, float b, char c = '\002') {
   bar(a);
   switch (c) {
   case '\001':
      break;              // func(a)
   case '\002':
      do_something(b):    // func(a, b)
      break;
   default:
      do_something(b, c); // func(a, b, c)
      break;
   }
   foo();
}
根据应用程序的不同,这可能更简单。

玩起来太晚了吗

您标记了C++14,但是,如果您可以使用C++17,那么可以使用if-constexpr

或者你添加了一个无参数的dou\u

或者,正如lubgr所建议的,您通过一个包装器调用do_某事,创建一个特殊的无参数包装器。

玩起来太晚了吗

您标记了C++14,但是,如果您可以使用C++17,那么可以使用if-constexpr

或者你添加了一个无参数的dou\u


或者,正如lubgr所建议的,您可以通过创建一个特殊的无参数包装器来调用do_某事。

您可以使用,但它可能更难阅读和理解。您可以使用,但它可能更难阅读和理解。可以使用std::is_invocable C++17或仅使用带有std::invoke_结果的SFINAE来恢复类型检查。std::转发某些内容这不是一个转发参考,也不会有什么效果。此外,如果OP没有do_somethingvoid,则此操作将失败,因此您需要使用回退来说明原因。@StoryTeller或使用constexpr,如果要在sizeof。。。args==0。@Botje-Not在C++14中可以使用std::is_invocable C++17,或者只使用std::invoke_result来恢复类型检查。std::转发非转发引用的内容不会有多大效果。此外,如果OP没有do_somethingvoid,则此操作将失败,因此您需要使用回退来说明原因。@StoryTeller或使用constexpr,如果要在sizeof。。。args==0。@Botje-不是在C++14中,而是创建一个包装器,我不能让void do_something{}吗?是的,这绝对是一个选项。我还以为你想离开办公室呢
d设置为原来的样子,但是如果你这样调整它,你就可以间接地去掉包装器。我不能创建一个包装器,我不能让void做一些事情{}?是的,这绝对是一个选项。我以为您想保持dou_something重载的设置不变,但是如果您这样调整它,您就可以取消包装器间接寻址。constexpr语句是否在编译时执行?如果是这样,那将是一个问题。由于我使用的库的发行版,我不得不坚持使用C++14。@harsh-if-constexpr,而不仅仅是constexpr。很遗憾,您不能使用C++17,因为它应该非常适合您。在本例中,测试是在编译时计算的,因为sizeof…Ts>0u是可计算的编译时,并且以下指令dou_somethingstd::forwardts。。。;当且仅当测试为真时才编译。在C++14中,我看不到不复制某些内容的方法。在编译时计算它可能是一个问题,因为在这种情况下,参数在运行时填充。但如果真的是这样,我需要重新考虑一下。@harsh-建议:如果可以的话,试试看。如果测试基于参数的数量,就不会是问题,因为它是C++的参数数必然是编译时间。编译时执行CONTXPR语句吗?如果是这样,那将是一个问题。由于我使用的库的发行版,我不得不坚持使用C++14。@harsh-if-constexpr,而不仅仅是constexpr。很遗憾,您不能使用C++17,因为它应该非常适合您。在本例中,测试是在编译时计算的,因为sizeof…Ts>0u是可计算的编译时,并且以下指令dou_somethingstd::forwardts。。。;当且仅当测试为真时才编译。在C++14中,我看不到不复制某些内容的方法。在编译时计算它可能是一个问题,因为在这种情况下,参数在运行时填充。但如果真的是这样,我需要重新考虑一下。@harsh-建议:如果可以的话,试试看。如果测试是基于参数的数量,就不能成为问题,因为它是C++的参数数必然是已知的编译时间。
int func(int a) {
   func(a, 0.0,'\001');
}

int func(int a, float b, char c = '\002') {
   bar(a);
   switch (c) {
   case '\001':
      break;              // func(a)
   case '\002':
      do_something(b):    // func(a, b)
      break;
   default:
      do_something(b, c); // func(a, b, c)
      break;
   }
   foo();
}
template <typename ... Ts>
int func (int a, Ts && ... ts)
 {
   bar(a);

   if constexpr ( sizeof...(Ts) > 0u )
      do_something(std::forward<Ts>(ts)...);

   foo();

   // and remember to return something of int
 }
int func (int a)
 {
   bar(a);    
   foo();

   // and remember to return something of int
 }


template <typename ... Ts>
int func (int a, Ts && ... ts)
 {
   bar(a);

   do_something(std::forward<Ts>(ts)...);

   foo();

   // and remember to return something of int
 }
void do_something ()
 { }