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

时间:2019-12-15 18:28:52

标签: c++ c++11 c++17

以下代码:

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

这里出了什么问题,然后怎么可能获得指向函数的指针?

3 个答案:

答案 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模板默认值。