c++ - 泛型 lambda 的实例化

标签 c++ templates lambda c++14

以下不编译:

#include <iostream>
#include <type_traits>

template <class F, class G>
auto static_if (std::true_type, F && f, G && g) {
    return std::forward<F> (f) (0);
}   

template <class F, class G>
auto static_if (std::false_type, F && f, G && g) {
    return std::forward<G> (g) (0);
}


template <class T> std::true_type constexpr is_pointer (T *) { return {}; }
template <class T> std::false_type constexpr is_pointer (T) { return {}; }

int main() {
    int x = 5;
    static_if (
        is_pointer (x),
        [&] (auto) { std::cout << *x << std::endl; },
        [&] (auto) { std::cout << "no pointer" << std::endl; }
    );
    return 0;
}

编译失败并显示错误信息:

prog.cpp: In lambda function:
prog.cpp:23:33: error: invalid type argument of unary '*' (have 'int')
      [&] (auto) { std::cout << *x << std::endl; },

参见此处:http://ideone.com/frl8rn

现在的问题是:为什么?

很明显,如果 lambda 不是通用的(没有 auto 参数),编译应该会失败。

然而,我们这里有两个通用 lambda。它们中的每一个都应该只在使用时实例化(这意味着:被调用,或者至少,当它的 operator () 以某种方式被引用时)。

因此,生成错误消息的通用 lambda 应该被实例化,因为使用了 static_if 的第二个重载,在其定义中参数 f 被调用。由于未使用通用 lambda 的 operator (),因此编译器应该简单地忽略它。

我的推理哪里错了?

最佳答案

在对已接受答案的评论中,您询问是否有更好的解决方案。可以说下面是一个(实时代码 here )。您不是在本地捕获 x,而是将您的 static_if 泛化为将任何参数一般地转发给两个 lambda 之一,并使您的 x 成为这样的参数。那么你就不需要在评论中使用虚拟变量了。

template <class F, class G, class ... Args>
auto static_if (std::true_type, F && f, G && g, Args && ... args) {
    return std::forward<F> (f) (std::forward<Args>(args)...);
}   

template <class F, class G, class ... Args>
auto static_if (std::false_type, F && f, G && g, Args && ... args) {
    return std::forward<G> (g) (std::forward<Args>(args)...);
}


template <class T> std::true_type constexpr is_pointer (T *) { return {}; }
template <class T> std::false_type constexpr is_pointer (T) { return {}; }

int main() {
    int x = 5;
    static_if (
        is_pointer (x),
        [] (auto x) { std::cout << *x << std::endl; },
        [] (auto x) { std::cout << "no pointer" << std::endl; },
        x
    );
    return 0;
}

关于c++ - 泛型 lambda 的实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38455947/

相关文章:

C++ MMap 一个文件到内存,然后获取一个文件描述符到该内存

C++ time() 给了我几乎随机的结果

c++ - 更改 wxDataViewCtrl 中的展开/折叠图标

Python Bottle - 模板中的内联 IF 语句

c++ - 模板 type_trait 函数,接受给定类型和/或派生类型的容器

Python按特定列对多维字典进行排序

c++ - vector 中数据的均匀分布

c# - 条件 Lambda

python - Lambda 不适用于过滤器

c++ - 编译期间模板优化中的static_cast