【问题标题】:Compiler-deduced type for generic lambdas泛型 lambda 的编译器推导类型
【发布时间】:2016-04-05 08:58:38
【问题描述】:

在this article中,出现如下代码:

std::vector<int> ivec = { 1, 2, 3, 4};
std::vector<std::string> svec = { "red", "green", "blue" };
auto adder = [](auto op1, auto op2){ return op1 + op2; };
std::cout << "int result : "
          << std::accumulate(ivec.begin(),
                             ivec.end(),
                             0,
                             adder)
          << "\n";
std::cout << "string result : "
          << std::accumulate(svec.begin(),
                             svec.end(),
                             std::string(""),
                             adder)
          << "\n";

如果我理解正确的话,编译器会生成一个类似这样的内部类:

template<class T>
class _lambda
{
  public:
  T operator()(T lhs, T rhs) { return lhs + rhs; }
};

但我不明白的是,在这段代码中,adder 似乎同时有两种类型:_lambda&lt;int&gt; 和_lambda&lt;string&gt;。这怎么可能?

【问题讨论】:

    标签: c++ lambda c++14 type-deduction


    【解决方案1】:

    根据标准 5.1.2/p5 Lambda 表达式 [expr.prim.lambda]:

    对于泛型 lambda,闭包类型具有公共内联函数 调用操作员成员模板 (14.5.2),其模板参数列表 由一个发明的类型模板参数组成,每次出现 auto 在 lambda 的参数声明子句中,按顺序 外观。

    因此,实际生成的是:

    class _lambda {
    public:
        template<typename T1, typename T2>
        auto operator()(T1 lhs, T2 rhs) const { return lhs + rhs; }
    };
    

    【讨论】:

    • 同样,如果参数是 likeauto &amp;&amp; lhs。然后它会生成T &amp;&amp; lhs.. 等等。
    【解决方案2】:

    不。它会生成如下内容:

    class _lambda {
    public:
        template<class T1, class T2>
        auto operator()(T1 lhs, T2 rhs) const { return lhs + rhs; }
    };
    

    该类没有模板化。 operator() 是。

    【讨论】:

    • 同样,如果参数是 likeauto &amp;&amp; lhs。然后它会生成T &amp;&amp; lhs.. 等等。
    • @Nawaz 在他的例子中他们不是
    【解决方案3】:

    事实上,编译器会生成一个如下所示的类:

    class _lambda {
    public:
        template<class T, class U>
        auto operator()(T lhs, U rhs) const { return lhs + rhs; }
    };
    

    这两个参数不一定属于同一类型,唯一的条件是存在具有相关参数类型的operator+()。

    查看coliru上的演示。

    【讨论】:

    • 同样,如果参数是 likeauto &amp;&amp; lhs。然后它会生成T &amp;&amp; lhs.. 等等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多