我来自python的世界,在那里我可以定义一系列操作,并在for循环中调用它们:
class AddOne:
def __call__(self, x, **common_kwargs):
return x+1
class Stringify:
def __call__(self, x, **common_kwargs):
return str(x)
class WrapNicely:
def __call__(self, s, **common_kwargs):
return "result="+s
data = 42
for operation in [AddOne(), Stringify(), WrapNicely()]:
data = operation(data)
output = data
(Note:目标是进行复杂的操作。理想情况下,可以给出共同的kwargs)
如果每次调用后的返回类型可以不同,那么C++中的等价物是什么?
我不确定我能找到任何接近,但我可能有错误的关键字搜索...
3条答案
按热度按时间dohp0rv51#
C++是静态类型的,所以这里的选项是有限的:
std::variant
对于第一种选择,你可以创建一个类模板,通过递归调用来执行函数,但是它比你的python代码要复杂一些:
注意:这需要使用至少C17的C标准。
k4emjkb12#
靶区; DR
使用范围内的成分:
Demo(使用简单)
Demo(创建一个
composer
抽象)为了更好地理解这在C中所带来的挑战,试着用type hints重新编写Python示例。尽管在一般情况下似乎"不可能"解决这个问题,但在C中,你可以用很多方法来解决这个问题。函数组合,就是你在这里使用它将最左边的操作的结果提供给右边的操作的方法。是一个"左折"运算符,如果您愿意冒险进入函数式编程领域,编写以下内容是可行的:
也就是说,即使有不同数量的输入,只要调用链可以组成,几年前我已经写了一系列关于这个主题的文章,可能this是最接近这个主题的。
也就是说,你也可以避免"函数的细微差别",使用一些很酷的C++20特性从头开始。下面是一个通用函数编写器的核心部分:
你可以用它来表示
编写器使用了一个C++20的变量捕获子句,这允许它管理任意长度的链。当然,一个适当的实现应该处理参数转发,如下所示
Demo
一个不需要辅助函数的小变化是(这里使用perf-forwarding处理):
Demo
8yoxcaq73#
在向python开发人员教授C时,您必须小心谨慎,以克服“C太复杂”的偏见。
在这方面,您有两种选择:
compose(f,g,h)
语法(这样可以保存您键入几个字符的时间),您应该自己生成一个composer。其他答案遵循此路径,为了简洁起见,我建议使用@NikosAthanasiou。所以,这是一个简短的版本:给定某个变量
x
,并假设它是一个数字(当您应用+1
时),您可以直接链接lambda:并将其用作
唯一遗漏的是从int到string的原地转换。对于这个,请参阅使用
std::variant
的其他答案,但为什么要使用它呢?...只有在真正需要时才使用它。