以下代码:
for i,j,k in list1:
x = j.split('.')[1]
print('{}{}'.format(i+x))
给出此错误:
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);
}
如此处所示:https://godbolt.org/z/nJiY4A
这里出了什么问题,然后怎么可能获得指向函数的指针?
答案 0 :(得分:2)
我想我知道为什么该行无法编译。它与重载解析无关,与decltype
无关:
[over.over] / 1 在某些情况下,使用不带参数的重载函数名可以解析为函数,特定函数的指向函数的指针或指向成员函数的指针,过载设置。在这种情况下,功能模板名称被认为是命名一组重载功能。如果
F
(可能在应用了函数指针转换(7.13)之后)与{相同,则为上下文中所需的目标类型的函数类型FT
选择类型F
的函数{1}}。目标可以是(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)。重载的函数名称可以在&运算符之前。 在列出的上下文之外的上下文中,不得在没有参数的情况下使用重载的函数名。
强调我的。仅在这些枚举上下文之外提及重载的函数名称-例如FT
中的-导致程序格式错误。通过明确拼写类型makes the code compile来避免这种有问题的用法:
decltype(&this_t::ins<F2, Args...>)
答案 1 :(得分:1)
我还不确定为什么使用重载函数的地址与调用它的行为有所不同。为什么前者会产生歧义,而后者却能够成功解决过载问题。
同时,这是一种可能的解决方法:
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...>;
}
};
调整是使第一个重载可以使用一个参数来调用,第二个重载可以使用两个或多个参数来调用。 Demo
答案 2 :(得分:0)
并非完全是您的要求,但是...如果您可以使用一个空的(不做任何事情,不做任何事情)地面递归案例,我提出以下解决方案
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
模板默认值。