gpt4 book ai didi

c++ - 强制 C++ 更喜欢带有隐式转换的重载而不是模板

转载 作者:行者123 更新时间:2023-12-04 16:38:17 25 4
gpt4 key购买 nike

我有一种情况,我需要重载解析来更喜欢带有隐式转换的重载而不是同名的模板函数。
考虑以下示例:

#include <iostream>
#include <functional>

void call_function(const std::function<void()>& function)
{
std::cout << "CALL FUNCTION 1" << std::endl;
function();
}

template <typename Function>
void call_function(const Function& function)
{
std::cout << "CALL FUNCTION 2" << std::endl;
function();
}

int main()
{
// Pass a lambda to "call_function"
// This lambda is implicitly convertible to 'std::function<void()>'
// Even though it is implicitly convertible, the template function is selected by the compiler.
call_function([]{
std::cout << "TEST" << std::endl;
});
}
输出:
CALL FUNCTION 2
TEST
不幸的是,编译器似乎检测到 call_function 的第一个实现将需要隐式转换将我传递的 lambda 转换为 std::function<void()>对象,因此它确定模板版本是更好的匹配并使用模板。我需要强制编译器更喜欢隐式转换重载而不是模板,因此输出将是:
CALL FUNCTION 1
TEST
我怎样才能做到这一点? (另请注意,我只能使用符合 C++11 的编译器,因此我无法使用 C++14 及更高版本的功能)

最佳答案

重载解析永远不会喜欢隐式转换而不是精确匹配。由于模板将始终完全匹配,因此选择非模板的唯一方法是确保它也不需要任何转换。
为此,您可以首先将闭包(lambda 表达式的结果)转换为正确的类型:

    call_function(static_cast<std::function<void()>>([]{
std::cout << "TEST" << std::endl;
}));
现在传递的正是第一个重载(“FUNCTION 1”)所采用的类型,因此将选择该类型。
也就是说,如果您关心调用的是哪个,您可能不应该使用重载。重载通常应保留用于重载本质上等效的情况,因此您真的不关心调用哪个。

关于c++ - 强制 C++ 更喜欢带有隐式转换的重载而不是模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66037162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com