C ++重载模式:具有可变lambda的调用解析 [英] C++ overload pattern : call resolution with mutable lambda

查看:47
本文介绍了C ++重载模式:具有可变lambda的调用解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Considering this well-known C++ pattern :

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会更改覆盖分辨率.

I wonder why declaring one of the parameter as a mutable lambda changes the override resolution.

实时示例在"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`
}

推荐答案

使用

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

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

both closures have const qualified operator()'s so int&& is a better match as it is not a template.

使用

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

您的 auto&&闭包不再具有const限定符,这意味着无需进行任何const限定符调整就可以调用它.这使重载成为身份完全匹配,而 int&& 重载需要const限定项调整.每个 [tab:over.ics.scs] ,因此您会看到名为 auto&& 的版本.

Your auto&& closure is not const qualified anymore, meaning there is no const qualification adjustment that needs to happen in order to call it. This makes that overload an identity exact match, while the int&& overload needs a const qualification adjustment. The identity exact match beats out a const qualification adjustment exact match per [tab:over.ics.scs] so that is why you see the auto&& version called.

这篇关于C ++重载模式:具有可变lambda的调用解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆