C++ 错误:无法解析对重载函数的引用
以下代码:C++ 错误:无法解析对重载函数的引用,c++,c++11,c++17,C++,C++11,C++17,以下代码: 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...&
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);
}
如图所示:
这里出了什么问题,怎么可能得到指向函数的指针呢?我还不确定为什么获取重载函数的地址与调用它的行为不同;为什么前者会产生歧义,而后者能够成功地解决过载问题 同时,这里有一个可能的解决方法:
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...>;
}
};
结构A
{
使用这个_t=A;
模板
无效ins(常数F1和fu)
{
}
模板
无效ins(常量F1和F1、常量F2和F2、常量参数和…参数)
{
这是ins(f2,args…);
//导致错误的行:
constexpr decltype(&this\t::ins)func=&this\t::ins;
}
};
调整是使第一个重载可以用一个参数调用,第二个重载可以用两个或更多参数调用 不完全是你要求的,但是。。。如果您可以使用空(不做任何事情,不接收任何东西)地面递归情况,我建议以下解决方案
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...>;
}
};
结构A
{
使用这个_t=A;
模板
无效ins()
{ }
模板
无效ins(F1常量和参数,参数常量和参数)
{
这是ins(args…);
//没有更多的错误
constexpr decltype(&this\t::ins)func=&this\t::ins;
}
};
这样,调用
ins
,当Args…
只是一种类型时(只有递归大小写匹配),当Args…
为空时,由于int=0
模板默认值,可以避免所有歧义。我想我知道该行无法编译的原因。它与重载解析关系不大,而与decltype有关:
[over.over]/1在某些上下文中,不带参数的重载函数名的使用解析为重载集中特定函数的函数、函数指针或成员函数指针。函数模板名称被认为是在这样的上下文中命名一组重载函数。如果F
(可能应用函数指针转换(7.13))与FT
相同,则为上下文中所需目标类型的函数类型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)
中)会导致程序格式错误。通过显式拼写类型来避免这种有问题的用法:
void(this_t::*func)(const Args&…)=&this_t::ins;
ins的两个版本都可以用一个参数调用。因此,一旦递归深入到ins(5),调用就不明确了。解决这个问题的一种方法是让第一个重载不带参数(而不是模板)。@igortandtnik它似乎并不含糊:@igortandtnik-“解决这个问题的一种方法是让第一个重载不带参数(而不是模板)。”-当调用未显式显示
模板参数时,此操作有效;在这种情况下,无参数基本情况必须是一个模板函数,具有不同的(不是类型,可能是值)模板参数和默认值;这种方法可以拦截ins()
调用。谢谢,您的解决方法似乎有效。尽管这种行为在我看来很奇怪,“我还不知道为什么取重载函数的地址的行为与调用它的行为不同,为什么?”?这不是很明显吗?调用函数时,提供用于解决重载的参数。获取地址时,不提供任何参数。@获取地址的代码行显式指定模板参数。从表面上看,它似乎应该为编译器提供与参数推断相同或更好的信息。而且三大编译器似乎都同意,如果多个函数模板都有名称,则模板id不是“重载函数名”,而是模板参数推断(无函数参数)并且替换成功,只替换了一个函数模板:我在标准中没有找到任何东西澄清这种情况。@aschepler也许那些编译器实现了更新的草稿,其中[over.over]p1已被大量重写,允许在所列之外的上下文中使用重载函数名。还有一个已经存在很长时间了。
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...>;
}
};
void (this_t::*func)(const Args&...) = &this_t::ins<Args...>;