c++ - 没有匹配 'std::function 的'max' 过载'
问题描述
此代码无法编译,并给出错误:
test.cpp:12:4: error: no matching function for call to 'func'
func(std::max<int>);
^~~~
test.cpp:4:6: note: candidate function not viable: no overload of 'max' matching 'std::function<const int &(const int &, const int &)>' for 1st argument
void func(std::function<const int &(const int &, const int &)> a)
^
1 error generated.
#include<iostream>
#include<functional>
#include <algorithm>
void func(std::function<const int &(const int &, const int &)> a)
// void func(const int &a(const int &, const int &)) //this one works
{
std::cout << a(4,5) << std::endl;
}
int main(int argc, char const *argv[])
{
func(std::max<int>);
}
我之前使用了一个具有相同参数签名的函数指针,std::function
并且有效。这里发生了什么?
解决方案
std 函数不是函数指针。
模板函数的名称在调用或转换为函数指针时会经历重载决议。传递给 std 函数时,它不会经历重载决议。
std::max<int>
可以引用多个函数;那些采用初始化列表或两个参数为int
s 的参数,每个参数都有带或不带比较器的重载。
使用重载决议,除了其中之一之外,所有这些都将被丢弃。没有,结果是模棱两可的。
int x00 = std::max<int>( std::initializer_list<int>{1,2,3,4} )
int x01 = std::max<int>( 2, 4 );
int x10 = std::max<int>( std::initializer_list<int>{1,2,3,4}, [](int a, int b){ return b>a; } )
int x11 = std::max<int>( 2, 4, [](int a, int b){ return b>a; } );
说std::max<int>
你是说正在使用这 4 个中的一个。
std::function
是的,其中只有一个可以与std::function
. (请注意,上述两个是无限的可能签名集)。
同时,
int const&(*ptr)(int const&,int const&) = std::max<int>;
在这里,我们正在做重载决议。我们选择std::max<int>
需要两个int
s 的。
std::function<int const&(int const&, int const&)> f = std::max<int>;
这里我们不对std::max
.
一个简单的解决方法是:
std::function<int const&(int const&, int const&)> f =
[](auto&&...args)->decltype(auto)
{ return std::max<int>(decltype(args)(args)...); };
我有时把它写成一个宏
#define RETURNS(...) \
noexcept(noexcept( __VA_ARGS__ )) \
-> decltype( __VA_ARGS__ ) \
{ return __VA_ARGS__; }
#define CALL(...) \
[](auto&&...args) \
RETURNS( __VA_ARGS__( decltype(args)(args)... ) )
给我们:
std::function<int const&(int const&, int const&)> f = CALL(std::max<int>);
在这里,我将重载解析延迟到调用传递的可调用对象之后f
。那时类型是已知的,所以一切正常。
推荐阅读
- discord.py - discord.py 删除用户(json)
- javascript - 如何将 ViolentMokey 用户脚本制作成浏览器扩展?
- c# - 如何解决“无法将当前 JSON 数组反序列化为类型,因为该类型需要 JSON 对象才能正确反序列化。”
- python-3.x - 使用python将图像放在另一个图像上
- rust - 更多关于在 rust 中重新实现 c++ timerqueue
- vb.net - 如何在 VB.net 中结束一个过程(子、函数)?
- javascript - 为什么添加分号会更改 Node.js REPL 中的结果?
- html - 缩略图和描述未显示在 Whatsapp 预览链接上
- amazon-web-services - 仅允许访问特定存储桶文件夹的 AWS 策略
- html - 将视频嵌入 HTML