指向具有自动返回'类型'的模板成员的指针在c ++中?

时间:2014-12-24 10:45:14

标签: c++ templates auto c++14 member-function-pointers

之前我必须在各种情况下使用指向成员函数的指针。通常,我使用mem_fun。但是,这是我第一次尝试在返回auto的成员模板上使用它。如果成员不是模板,它对auto返回'类型'有效,如果指定了返回类型,它对成员模板有效。此外,我尝试将预期的类型直接传递给mem_fun(),但它没有帮助。

任何不依赖mem_fun()的替代解决方案也将受到赞赏。

以下是由于以下错误而无法编译的代码:

  

没有用于调用'mem_fun()'的匹配函数。

应该注意的是,如果autoint替换,则代码会编译。此外,如果保留auto,但template<int N><1>,则代码也会按预期编译并运行。

class Q
{

public:
    int myq;

    template<int N>
    auto mymethod(int a)
        {
            std::cout << myq*a << std::endl;
        }
    void setint(int a)
        {
            myq = a;
        }
};


int main()
{

    boost::function<void (int)> p_member;
    Q q;
    p_member = std::bind1st(
        std::mem_fun(
            &Q::mymethod<1>
            ),
        &q
        );
    q.setint(1);
    p_member(100);
//...
}

1 个答案:

答案 0 :(得分:2)

这不是auto特有的,它是GCC的一般限制。在某些情况下,它只是没有意识到,如果在指定模板参数后,它只能引用一个可能的函数,则它指的是该函数。对于大多数代码而言,它并不重要,并且对于大多数重要的情况,GCC已经解决了这些限制,但有时它确实浮出水面。很久以前我报告过类似的问题:

template <int> void f() {}
int main() { return f<0> != f<0>; }

这应该将f<0>的地址与f<0>的地址进行比较,因此应该返回零,但是GCC无法确定f<0>没有超载,并抱怨:

  

错误:类型'&lt;未解析的重载函数类型&gt;'和'&lt;未解析的重载函数类型&gt;'的无效操作数到二元'运算符!='

在这里,一个解决方法是添加一个无意义的无操作,说服编译器尝试更难以确定类型:return &f<0> != &f<0>;确实有效。

类似的方法也可用于您的代码。虽然此处无法添加&运算符,但其他无操作可行:

p_member = std::bind1st(
    std::mem_fun(
        true ? &Q::mymethod<1> : nullptr
        ),
    &q
    );

我认为没有理由认为您的代码可能无效。它被其他编译器(至少是clang)接受了,如果它是无效的,那么我的解决方法肯定是无效的,原因完全相同。