C++ 标准库方法的成员函数指针问题
这个问题源自C++ 标准库方法的成员函数指针问题,c++,templates,c++11,standard-library,member-function-pointers,C++,Templates,C++11,Standard Library,Member Function Pointers,这个问题源自 . 你不必读这些来理解这个问题。这两个问题的答案可能相同 我越来越累了 在网上冲浪之后,我看到了这篇帖子: 虽然它是相关的,但并不能解决问题 问题:在标准库方法的情况下,当相同的东西传递给手写类方法时,为什么成员函数替换失败 更新: 看了正确答案后,我确信insert不能使用。唯一的办法就是难看的打字,这对解决这个问题来说是一种过分的手段。 一个优雅的解决方案是使用std::set::emplace,它只有模板d版本,而insert则混合了模板和非模板版本。 按如下方式调用函数:
.
你不必读这些来理解这个问题。这两个问题的答案可能相同 我越来越累了 在网上冲浪之后,我看到了这篇帖子:
虽然它是相关的,但并不能解决问题 问题:在标准库方法的情况下,当相同的东西传递给手写类方法时,为什么成员函数替换失败 更新: 看了正确答案后,我确信
insert
不能使用。唯一的办法就是难看的打字,这对解决这个问题来说是一种过分的手段。一个优雅的解决方案是使用
std::set::emplace
,它只有模板
d版本,而insert则混合了模板
和非模板
版本。按如下方式调用函数:
ReceiveFuncPtr(&std::set<int>::emplace<const int&>);
ReceiveFuncPtr(&std::set::emplace);
上述。问题不在于您在
MySet
中显示的insert
函数。问题是你遗漏了其中一个。具体而言:
template< class InputIt >
void insert( InputIt first, InputIt last );
template
无效插入(先输入,后输入);
从[临时扣减呼叫]:
当p是函数类型时,指向函数类型的指针或指向成员函数类型的指针:-如果参数是包含一个或多个函数模板的重载集,则将处理该参数 作为一种非演绎的语境
因为正是这样一个重载集,所以该参数是非推断上下文,无法解析。您的
MySet
示例不包含insert
的函数模板重载,这就是它工作正常的原因。如果您添加一个,您将看到它也将无法编译。它实际上可以使用visual studio 2013在MSVC上编译并运行良好:template T exec(Ret(T::*func)(const int&i)){T T;(T.*func)(4);返回T;}
Yes,并添加一个template
function函数。我跳过了该函数,认为它与本例无关:-)。如果您能为实际问题提出一个优雅的解决方案,即如何使用此约束实现ReceiveFuncPtr()
,这将是一个额外的好处。@iammilind您必须将其转换为正确的类型。在本例中,这是一个很好的例子:ReceiveFuncPtr(static_cast(&std::set::insert))
或者您可以编写一个没有此类函数模板的类insert
。我已经用一个可能的解决方案更新了您的答案,现在我将使用它。使用emplace()
函数。希望您能接受。:-)@iammilindemplace
之所以有效,是因为您明确提供了正确的函数,而不是因为它只是模板化的。@Barry,这是正确的。我的看法是:如果是emplace
,我们不必像对待insert
那样进行难看的打字。只需添加一个额外的模板
参数。简言之,我是从“干净”的角度思考的。
template<typename T, typename T2 = void>
struct MySet
{
std::pair<T,bool> insert (const T& i) { return std::pair<T,bool>(T(),true); }
std::pair<T,bool> insert (T&& i) { return std::pair<T,bool>(T(),true); }
void insert (std::initializer_list<T> i) { return false; }
}
int main ()
{
ReceiveFuncPtr(&MySet<int>::insert); // OK
}
ReceiveFuncPtr(&std::set<int>::emplace<const int&>);
template< class InputIt >
void insert( InputIt first, InputIt last );