模板化 lambda 的显式实例化

wim*_*aan 5 c++ lambda templates c++20

我刚刚遇到显式实例化模板 lambda 的问题。下面的代码无法编译,但我无法弄清楚这种情况下出了什么问题:

        [&]<auto... II>(std::index_sequence<II...>) {
            auto check = [&]<auto I>(){
            };
            (check<II>(),...);
        }(std::make_index_sequence<N>{});
Run Code Online (Sandbox Code Playgroud)

编译器错误(gcc trunk:11.0.0):

rswitch.cc: In lambda function:
rswitch.cc:42:28: error: expected primary-expression before ')' token
42 |                 (check<II>(),...);
|                            ^
rswitch.cc:42:26: error: binary expression in operand of fold-expression
42 |                 (check<II>(),...);
Run Code Online (Sandbox Code Playgroud)

我看起来必须像这样使用模板消歧:

        [&]<auto... II>(std::index_sequence<II...>) {
            auto check = [&]<auto I>(){
            };
            (this->template check<II>(),...);
        }(std::make_index_sequence<N>{});
Run Code Online (Sandbox Code Playgroud)

还有其他方式可以表达这一点吗?

Sto*_*ica 5

check本身不是模板。它是一个未指定闭包类型的对象,包含

template<auto I> void operator()();
Run Code Online (Sandbox Code Playgroud)

成员函数是模板。

该错误是由于尝试向 提供模板参数造成的check。这又不是模板本身。lambda 函数调用运算符的模板参数需要可推导(即使它们已命名),函数调用语法才能正常工作。C++20 并没有改变这一点。

显式指定参数的唯一方法是相当难看的

check.template operator()<II>()
Run Code Online (Sandbox Code Playgroud)

但相反,使其可推导可能会更好。

[&]<auto... II>(std::index_sequence<II...>) {
    auto check = [&]<auto I>(std::integral_constant<decltype(I), I>){
    };
    (check(std::integral_constant<decltype(II), II>{}),...);
}(std::make_index_sequence<N>{});
Run Code Online (Sandbox Code Playgroud)

显式指定size_t也是一种替代使用的选项decltype(I)