简体   繁体   中英

Templatd lambda calling templated lambda (C++20) doesn't work with clang 12 / 13

Consider this code:

#include <utility>
#include <functional>

using namespace std;

int main( int argc, char **argv )
{
    static
    auto lA = []<bool FLAG_A, bool FLAG_B>( unsigned a ) -> unsigned
    {
        return (unsigned)FLAG_A + FLAG_B + a;
    };
    static
    auto lB = []<bool FLAG_A, bool FLAG_B>( unsigned a ) -> unsigned
    {
        return lA.template operator ()<FLAG_A, FLAG_B>( a );
    };
    using fn_t = function<unsigned ( unsigned )>;
    fn_t fn = bind( &decltype(lB)::template operator ()<false, false>, &lB, placeholders::_1 );
}

This compiles without any problems with MSVC 2019, but clang 12 / 13 gives the following errors:

test.cpp(11,12): error: multiple overloads of '__invoke' instantiate to the same signature 'auto (unsigned int) const -> unsigned int'
        auto lA = []<bool FLAG_A, bool FLAG_B>( unsigned a ) -> unsigned
                  ^
test.cpp(11,12): note: in instantiation of member class '' requested here
test.cpp(21,42): note: in instantiation of function template specialization 'main(int, char **)::(anonymous class)::operator()<false, false>' requested here
        fn_t fn = bind( &decltype(lB)::template operator ()<false, false>, &lB, placeholders::_1 );
                                                ^
test.cpp(11,12): note: previous implicit declaration is here
        auto lA = []<bool FLAG_A, bool FLAG_B>( unsigned a ) -> unsigned
                  ^

gcc 11 also compiles the code without any errors. Is there a way to make the code to work with clang also without any elaborate workarounds?

There is stillstd::integral_constant (and even std::bool_constant in your case) to allow deduction:

static auto lA = []<bool FLAG_A, bool FLAG_B>(std::bool_constant<FLAG_A>,
                                              std::bool_constant<FLAG_B>,
                                              unsigned a ) -> unsigned
{
    return (unsigned)FLAG_A + FLAG_B + a;
};
static
auto lB = []<bool FLAG_A, bool FLAG_B>( unsigned a ) -> unsigned
{
    return lA(std::bool_constant<FLAG_A>{}, std::bool_constant<FLAG_B>{}, a);
};

Demo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM