基于条件的远期变异论证
我想实现以下行为:
enum class Fruit {
Apple,
Orange,
Pear,
};
template<typename... Args>
void processFruit(Fruit fruit_type, Args&&... args) {
switch (fruit_type) {
case Apple:
processApple(std::forward<Args>args...);
break;
case Orage:
processOrange(std::forward<Args>(args)...);
break;
default:
break;
}
postProcessing();
return;
}
ProcessApple
和processorange
采取不同数量的参数。 当然,这不能编译。编译器无法基于switch
语句实例化函数。我在static_if
上找到了一些建议。只是想知道我的情况是否有更简单的方法。谢谢。
PS我的平台将我限制在C ++ 14解决方案上。
I would like to achieve following behavior:
enum class Fruit {
Apple,
Orange,
Pear,
};
template<typename... Args>
void processFruit(Fruit fruit_type, Args&&... args) {
switch (fruit_type) {
case Apple:
processApple(std::forward<Args>args...);
break;
case Orage:
processOrange(std::forward<Args>(args)...);
break;
default:
break;
}
postProcessing();
return;
}
processApple
and processOrange
take different number of arguments.
This of course cannot compile. Compiler cannot instantiate functions based on the switch
statement. I found some suggestions on static_if
. Just wondering if there's a simpler way for my situation. Thanks.
p.s. my platform restricts me on C++14 solutions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题会弄乱水域,因为您正在混合运行时和编译时间逻辑,因为在您的情况下,函数参数的数量和类型取决于某物的运行时值。
现在,您会遇到两个不同的选择:可以进行这项工作(即使在C ++ 14中),但是任何未通过正确参数的呼叫站点都将在运行时无法检测到。这样做的方法是借助
std :: enable_if_t
,exptype()
和std :: dectval
。我已经为您的示例完成了此操作,并且在C ++ 14模式下为我编译了以下编译:(struct处理器
只是为了清理名称空间,它们可能是全局函数。)这里的问题是编译器无法检测到错误的呼叫,请参阅processFruit的评论(fruat :: pear,1.234,77);
会产生例外,但编译器无法检测到它在编译时。在我看来,这不是很明智。由于参数取决于
fruit
无论如何类型,我真的看不到当fruit> fruit
参数仅知道时,您什至无法执行这些功能之一的调用。运行时,因为每个呼叫站点仅适用于一种类型。而且,如果您确实知道在编译时,可以通过超载以更简单的方式来完成这一点,这也允许更好地编译时间诊断:
这都说,我怀疑您的代码中存在一些更高级别的设计问题,但我们将无法理解您提供的有限示例。
Your question muddies the waters a bit, because you're mixing runtime and compile-time logic, because in your case the number and types of function arguments depends on the runtime value of something.
You're now stuck with two different options: it is possible to make this work (even in just C++14), but any call site that doesn't pass the correct arguments will not be detected until runtime. The way to do so is with the help of
std::enable_if_t
,decltype()
andstd::declval
. I've done this for your example, and the following compiles for me in C++14 mode:(The
struct Processor
is just to clean up the namespace, they could be global functions.) Problem here is that the compiler can't detect a wrong call, see the commented out call toprocessFruit(Fruit::Pear, 1.234, 77);
that would generate an exception, but the compiler couldn't detect it at compile time.In my eyes this is not very sensible though. Since the arguments depend on the
Fruit
type anyway, I don't really see how you could even perform a call to one of these functions when theFruit
argument is only known at runtime, because each call site will only work for a single type.And if you do know that at compile time anyway, this could be done in a much simpler way via overloads, that also allows for much better compile-time diagnostics:
That all said, I suspect there's some higher-level design problem in your code, but we won't be able to understand that with the limited example you've provided.