使用std::function:帮助编译器消除歧义的重载函数解析
overloaded function resolution with std::function: helping compilers disambiguate
我想从一个重载的模板函数创建一个std::function
。使用g++ -std=c++14编译时,我得到了一个重载解析错误。我有一个hack按摩函数模板成编译器识别的形式,但我想知道是否有更优雅的方法。下面的代码说明了错误和我的hack
#include <functional>
template <typename T>
T foo(T t) { return t; }
template <typename T>
T foo(T t1, T t2){ return t1 + t2; }
int main (){
//error: conversion from ‘<unresolved overloaded function type>’
//to non-scalar type ‘std::function<double(double)>’ requested
std::function<double(double)> afunc = &foo<double>;
//my workaround to 'show' compiler which template
//function to instantiate
double (*kmfunc1)(double) = &foo<double>;
std::function<double(double)> afunc = kmfunc1;
}
我有两个问题
- 期望编译器解析使用哪个模板是不合理的吗? 在上述情况下,创建std::函数的最优雅的方法是什么?
#define OVERLOAD_SET(...)
[](auto&&...args)->
decltype(__VA_ARGS__(decltype(args)(args)...))
{
return __VA_ARGS__(decltype(args)(args)...);
}
创建一个对象,该对象表示其参数的完整(全局)重载集。(我使用...
作为宏,不理解,
在现代c++中的所有用途)
std::function<double(double)> afunc = OVERLOAD_SET(foo<double>);
std::function<double(double,double)> bfunc = OVERLOAD_SET(foo<double>);
两个都可以,
也可以std::function<double(double)> afunc = OVERLOAD_SET(foo);
std::function<double(double,double)> bfunc = OVERLOAD_SET(foo);
当我们在它。这里的思想是将重载解析推迟到参数确定的时候。
OVERLOAD_SET(foo)
编译为:
[](auto&&...args)
->decltype(foo(decltype(args)(args)...))
{
return foo(decltype(args)(args)...);
}
是一个无状态的lambda,它返回在其参数上调用foo
所做的任何事情。
- 期望编译器解析使用哪个模板是不合理的吗?
编译器不允许根据c++语言规则解析使用哪个模板。相关的std::function
构造函数是:
template< class F >
function( F f );
并且,根据[temp. deduction .type]:
如果一个模板形参只在非推导式中使用如果没有显式指定,则模板参数推导失败。
未推断的上下文是:
- - - - - -[…]
-一个函数形参,其实参演绎不能进行,因为关联函数是一个函数,或者是一组重载函数(13.4),并且适用以下一个或多个条件:
- 多个函数匹配函数形参类型(导致歧义演绎),或
-没有函数匹配函数参数类型,否则
-作为参数提供的函数集包含一个或多个函数模板。
- - - - - -[…)
因此传入&foo<double>
是一个非推导的上下文,模板推导失败,因此出现编译错误。
在上述情况下,创建std::函数的最优雅的方法是什么?
我只会使用强制转换:
std::function<double(double)> afunc =
static_cast<double(*)(double)>(&foo<double>);
,然后向标准委员会抱怨为什么std::function<Sig>
没有一个接受Sig*
的构造函数。按照你想要的顺序。
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 可以打印矢量和矢量中的矢量的非重载C++函数
- 错误 没有与参数列表匹配的重载函数"getline"实例
- 使用模板重载函数
- C++线程中,没有重载函数接受 X 参数
- std::vector 没有重载函数的实例与参数列表匹配
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- 错误:无法解析对重载函数的引用;你的意思是调用它吗?
- 对重载函数find_first_not_of的不明确调用
- 如何从重载解析中删除重载函数?
- CUDA:重载函数"isnan"的多个实例
- C++派生类重载函数(带有 std::function 参数)不可见
- 避免在人为的重载函数调用中拼写出类型
- C++:如何为多个重载函数保留通用代码路径?
- 什么时候可以使用常量装饰调用我的重载函数?
- 尝试使用谓词函数会导致错误:"std::sort"未找到匹配的重载函数
- std::调用,未找到匹配的重载函数
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 为什么使用不匹配的参数调用重载函数仍然有效
- 如何通过签名作为模板参数来解决重载函数?