簡體   English   中英

Lambda inheritance 使用包擴展

[英]Lambda inheritance using pack expansion

我正在研究 lambda inheritance 並嘗試在此stackoverflow 鏈接下更改以下示例。 我使用模板推導指南和折疊表達式修改了代碼。

一段代碼

#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

出了什么問題?

代碼示例 -->演示

using Ts::operator()...;

這會將所有operator()從基類“提升”到 class 命名空間中。

這顯然不是你想要的。 看起來您想按順序執行構成基類的操作。

以下是如何使用逗號運算符以漂亮的方式編寫它:

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

住在科利魯

#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"

筆記

我建議私下繼承,並使函數要么對參數進行 void 操作,要么使它們成為純函數(獲取 const 引用並返回副本)。 此外,請參閱C++ / C++11 中的 function 組合物,例如

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM