错误:无法解析对重载函数的引用

error: reference to overloaded function could not be resolved

本文关键字:重载 函数 引用 错误      更新时间:2023-10-16

以下代码:

struct A
{
using this_t = A;
template <class F1>
void ins(const F1& fu)
{
}
template <class F1, class... Args>
void ins(const F1& fu, const Args&... args)
{
this_t::ins<Args...>(args...);
// the line which is causing the error:
constexpr decltype(&this_t::ins<Args...>) func = &this_t::ins<Args...>;
}
};
int main()
{
A a;
a.ins(5, 5, 5, 5, 5);
}

给出此错误:

error: reference to overloaded function could not be resolved

如图所示:https://godbolt.org/z/nJiY4A

这里出了什么问题,那么如何获得指向函数的指针?

我想我知道为什么那行无法编译。它与过载分辨率关系不大,而与decltype有关:

[over.over]/1在某些情况下,使用不带参数的重载函数名称会解析为重载集中特定函数的函数、函数指针或成员函数的指针。函数模板名称被视为在此类上下文中命名一组重载函数。如果上下文中所需的函数类型FTF(在可能应用函数指针转换 (7.13(之后(与FT相同,则选择类型为F的函数作为上下文中所需的目标类型的函数类型。目标可以是

(1.1( — 正在初始化的对象或引用 (11.6, 11.6.3, 11.6.4(,(1.2( — 赋值的左侧 (8.18(,(1.3( — 函数的参数 (8.2.2(,(1.4( — 用户定义运算符的参数 (16.5(,

(1.5( — 函数、运算符函数或转换的返回值 (9.6.3(,(1.6( — 显式类型转换 (8.2.3, 8.2.9, 8.4(,



(1.7( — 非类型模板参数 (17.3.2(。

重载函数名称前面可以加上 & 运算符。重载函数名称不得在列出的上下文之外没有参数的情况下使用。

强调我的。只是在这些枚举上下文之外提及重载的函数名称 - 例如在decltype(&this_t::ins<F2, Args...>)中 - 会使程序格式不正确。通过显式拼写类型来避免这种有问题的用法,可以使代码编译:

void (this_t::*func)(const Args&...) = &this_t::ins<Args...>;

我还不确定为什么获取重载函数的地址与调用它的行为不同; 为什么前者会产生歧义,而后者能够成功解决重载。

同时,这里有一个可能的解决方法:

struct A
{
using this_t = A;
template <class F1>
void ins(const F1& fu)
{
}
template <class F1, class F2, class... Args>
void ins(const F1& f1, const F2& f2, const Args&... args)
{
this_t::ins<F2, Args...>(f2, args...);
// the line which is causing the error:
constexpr decltype(&this_t::ins<F2, Args...>) func = &this_t::ins<F2, Args...>;
}
};

调整是使第一个重载可以使用一个参数调用,第二个重载可以使用两个或更多参数调用。演示

不完全是你问的,但是...如果你可以使用一个空的(什么都不做,什么都不接收(地面递归情况,我提出以下解决方案

struct A
{
using this_t = A;
template <int = 0>
void ins ()
{ }
template <typename F1, typename ... Args>
void ins (F1 const &, Args const & ... args)
{
this_t::ins<Args...>(args...);
// no more error
constexpr decltype(&this_t::ins<Args...>) func = &this_t::ins<Args...>;
}
};

这样,调用ins<Args...>,当Args...仅是一种类型(只有递归大小写匹配(时,您可以避免所有歧义,当Args...为空时,由于int = 0模板默认值,与基本情况匹配。