【发布时间】:2020-01-16 13:46:54
【问题描述】:
我一直在尝试解决 C++ 中的下一个函数问题:
template <typename T>
auto createFunction(T& ClosuredData) {
template <typename U>
return [&](function<void(T&, U&)> Callback) {
return [&](U& DataFromCallback) {
Callback(ClosuredData, DataFromCallback);
};
};
};
// example use
struct Person {
string name{"Foo"};
int age = 20;
}
Person foo{};
auto mutate = createFunction(foo);
auto changeAge = mutate<int>([](Person& person, int& age) {
person.age = age;
})
changeAge(20)
所以基本上是一个带有内部模板 lambda 的模板函数创建者。
但当然,据我所知,内部模板在 C++ 中是不可能的。
我尝试将回调设置为自动类型,但当然我无法推断出 DataFromCallback 导致错误的类型安全。
我能否在不引入类/结构的情况下以某种方式实现适当的类型安全?
编辑: 我看到的“解决方案”之一是使用自动类型而不是功能:
template <typename T>
auto CreateFunction(T& ClosuredData) {
return [&](auto Callback) {
return [&, Callback](auto DataFromCallback) {
Callback(ClosuredData, DataFromCallback);
};
};
};
这确实很酷,但给人一种类型安全的错误感觉,例如:
{
Person person{};
auto personMutator = CreateFunction(person);
auto changeAge = personMutator([](Person& person, int age) {
person.age = age;
});
changeAge(""); // Would not throw an error in this line, but at an upper stack
changeAge(any); // same stuff
}
【问题讨论】:
-
即使你创建了这样一个 lambda(它可以使用新的 C++20 语法),
mutate<int>(params)也不起作用。您必须使用mutate.operator()<int>(params)调用它,或者将参数转换为std::function。 -
为什么不引入结构/类名如此重要?这将使您的代码远更具可读性,因为人们实际上可以追踪类型名称并弄清楚发生了什么。
-
没那么重要,我只是想看看有没有可能。非常喜欢函数式编程。
标签: c++ templates lambda functional-programming