提问者:小点点

C++重载模式:使用可变lambda调用解析


考虑到这个众所周知的C++模式:

template <class... Ts> struct overload : Ts... { using Ts::operator()...; };
template <class... Ts> overload(Ts...) -> overload<Ts...>; // clang needs this deduction guide,
                                                           // even in C++20 for some reasons ...

我想知道为什么将其中一个参数声明为可变lambda会改变重写解析。

godbolt上的活生生的例子:

#include <iostream>

template <class... Ts> struct overload : Ts... { using Ts::operator()...; };
template <class... Ts> overload(Ts...) -> overload<Ts...>; // clang needs this deduction guide,
                                                           // even in C++20 for some reasons ...

auto main() -> int
{
    auto functor_1 = overload{
        [](int &&){
            std::cout << "int\n";
        },
        [](auto &&) {   // making this lambda `mutable` makes deduction mismatch ?
            std::cout << "smthg else\n";
        }
    };
    functor_1(42); // prints `int`

    auto functor_2 = overload{
        [](int &&){
            std::cout << "int\n";
        },
        [](auto &&) mutable {
            std::cout << "smthg else\n";
        }
    };
    functor_2(42); // prints `smth else`
}

共1个答案

匿名用户

auto functor = overload{
    [](int &&){
        std::cout << "int\n";
    },
    [](auto &&) {
        std::cout << "smthg else\n";
    }
};
functor(42); // prints `int`

这两个闭包都有const限定的operator()的,因此int&&是更好的匹配项,因为它不是模板。

auto functor = overload{
    [](int &&){
        std::cout << "int\n";
    },
    [](auto &&) mutable {
        std::cout << "smthg else\n";
    }
};
functor(42); // prints `smthg else`

您的auto&&闭包不再是常量限定的,这意味着调用它不需要进行常量限定调整。这使得该重载与标识完全匹配,而int&&重载需要进行常量限定调整。identity的精确匹配胜过[tab:over.ics.scs]的常量限定调整的精确匹配,因此您看到调用auto&版本的原因就在于此。

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(c++|重载|模式|可变|lambda|调用|解析)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?