之前我必须在各种情况下使用指向成员函数的指针。通常,我使用mem_fun
。但是,这是我第一次尝试在返回auto
的成员模板上使用它。如果成员不是模板,它对auto
返回'类型'有效,如果指定了返回类型,它对成员模板有效。此外,我尝试将预期的类型直接传递给mem_fun()
,但它没有帮助。
任何不依赖mem_fun()
的替代解决方案也将受到赞赏。
以下是由于以下错误而无法编译的代码:
没有用于调用'mem_fun()'的匹配函数。
应该注意的是,如果auto
被int
替换,则代码会编译。此外,如果保留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);
//...
}
答案 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)接受了,如果它是无效的,那么我的解决方法肯定是无效的,原因完全相同。