c++ - 使用包扩展的 Lambda 继承

标签 c++ lambda overriding c++17 fold

我正在研究 lambda 继承,我尝试更改以下示例 在此下stackoverflow link 。我使用模板推导指南和折叠表达式修改了代码。

一段代码

#include <iostream>
using namespace std;

template<class... Ts>
class FunctionSequence :Ts...
{
    using Ts::operator()...;
};
template <class...Ts> FunctionSequence(Ts...) -> FunctionSequence<Ts...>; // (1)

int main(){

    //note: these lambda functions are bug ridden. Its just for simplicity here.
    //For correct version, see the one on coliru, read on.
    auto trimLeft = [](std::string& str) -> std::string& { str.erase(0, str.find_first_not_of(' ')); return str; };
    auto trimRight = [](std::string& str) -> std::string& { str.erase(str.find_last_not_of(' ')+1); return str; };
    auto capitalize = [](std::string& str) -> std::string& { for(auto& x : str) x = std::toupper(x); return str; };

    auto trimAndCapitalize = FunctionSequence{trimLeft, trimRight, capitalize};
    std::string str = " what a Hullabaloo     ";

    std::cout << "Before TrimAndCapitalize: str = \"" << str << "\"\n";
    trimAndCapitalize(str);
    std::cout << "After TrimAndCapitalize:  str = \"" << str << "\"\n";

    return 0;
}

但是我收到以下错误

<source>: In function 'int main()':
<source>:19:78: error: no matching function for call to 'FunctionSequence<main()::<lambda(std::string&)>, main()::<lambda(std::string&)>, main()::<lambda(std::string&)> >::FunctionSequence(<brace-enclosed initializer list>)'
   19 |     auto trimAndCapitalize = FunctionSequence{trimLeft, trimRight, capitalize};
      |                                                                              ^
<source>:5:7: note: candidate: 'constexpr FunctionSequence<main()::<lambda(std::string&)>, main()::<lambda(std::string&)>, main()::<lambda(std::string&)> >::FunctionSequence(const FunctionSequence<main()::<lambda(std::string&)>, main()::<lambda(std::string&)>, main()::<lambda(std::string&)> >&)'
    5 | class FunctionSequence :Ts...
      |       ^~~~~~~~~~~~~~~~
<source>:5:7: note:   candidate expects 1 argument, 3 provided
<source>:5:7: note: candidate: 'constexpr FunctionSequence<main()::<lambda(std::string&)>, main()::<lambda(std::string&)>, main()::<lambda(std::string&)> >::FunctionSequence(FunctionSequence<main()::<lambda(std::string&)>, main()::<lambda(std::string&)>, main()::<lambda(std::string&)> >&&)'
<source>:5:7: note:   candidate expects 1 argument, 3 provided
ASM generation compiler returned: 1

出了什么问题?

代码示例 --> demo

最佳答案

using Ts::operator()...;

这会将所有operator()从基类“提升”到类命名空间中。

这显然不是您想要的。看起来您想要按顺序执行组成的基类操作。

以下是如何使用逗号运算符以巧妙的方式编写它:

template<class... Ts>
struct FunctionSequence : Ts...  {
    auto operator()(std::string& str) const {
        return (Ts::operator()(str), ...);
    }
};

<强> Live On Coliru

#include <iostream>
using namespace std;

template<class... Ts>
struct FunctionSequence : Ts...  {
    auto operator()(std::string& str) const {
        return (Ts::operator()(str), ...);
    }
};
template <class...Ts> FunctionSequence(Ts...) -> FunctionSequence<Ts...>; // (1)

int main(){
    //note: these lambda functions are bug ridden. Its just for simplicity
    //here.  For correct version, see the one on coliru, read on.
    auto trimLeft = [](std::string& str) -> std::string& { str.erase(0, str.find_first_not_of(' ')); return str; };
    auto trimRight = [](std::string& str) -> std::string& { str.erase(str.find_last_not_of(' ')+1); return str; };
    auto capitalize = [](std::string& str) -> std::string& { for(auto& x : str) x = std::toupper(x); return str; };

    auto trimAndCapitalize = FunctionSequence{trimLeft, trimRight, capitalize};
    std::string str = " what a Hullabaloo     ";

    std::cout << "Before TrimAndCapitalize: str = \"" << str << "\"\n";
    trimAndCapitalize(str);
    std::cout << "After TrimAndCapitalize:  str = \"" << str << "\"\n";

    return 0;
}

打印

Before TrimAndCapitalize: str = " what a Hullabaloo     "
After TrimAndCapitalize:  str = "WHAT A HULLABALOO"

注释

我建议私有(private)继承,并使函数对参数进行无效操作,使它们成为纯函数(采用常量引用并返回拷贝)。另请参阅function composition in C++ / C++11例如

关于c++ - 使用包扩展的 Lambda 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65448942/

相关文章:

C++ auto_ptr在传递给函数时被破坏

c++ - CComSafeArray 更改元素数

c++ - 什么是更好的Matrix4x4类设计c++新手

C# 如何解决 Func<T, bool> 中的逆变问题?

java - 它是否重载或覆盖?

javascript - 如何 "override"原型(prototype)上定义的(get-)属性?

特定位大小的 C++ 指针

parameters - 参数周围没有括号的方案 Lambda 表达式

c# - Entity Framework - 无法将 lambda 表达式转换为类型 'string',因为它不是委托(delegate)类型

variables - docker-compose 覆盖应用程序属性