【问题标题】:Pointer to deque<int>::push_back指向 deque<int>::push_back 的指针
【发布时间】:2016-12-06 13:36:02
【问题描述】:
#include <iostream>
#include <deque>

using namespace std;
main()
{
    typedef void (deque<int>::*func_ptr)(int);
    func_ptr fptr = &deque<int>::push_back;
}

我试图获取指向此函数的指针,但出现编译错误

error: cannot convert ‘void (std::deque<int>::*)(const value_type&) {aka void (std::deque<int>::*)(const int&)}’ to ‘func_ptr {aka void (std::deque<int>::*)(int)}’ in initialization
     func_ptr fptr = &deque<int>::push_back;

我想这样做,以便我可以根据不同的条件获得指向不同成员函数的指针。

我推荐了this link

【问题讨论】:

  • 您链接的讲义不再公开访问。
  • @ti7 我仍然可以访问它。

标签: c++ pointers function-pointers


【解决方案1】:

正如在接受的答案中所说,问题在于类型签名不同 - 对于std::deque&lt;T&gt;push_back 仅具有接受 T const&amp; 的重载,而不是直接接受 Ttypedef void (deque&lt;int&gt;::*func_ptr)(const int &amp;) 是一种非常简洁和愉快的写法。

我想提出一种 C++11 方法来做到这一点——类型别名。人们可能首先想知道“为什么不使用auto?”这是不可能的,因为被访问的函数是一个重载函数,而auto 不知道要访问哪个重载。因为原始问题嵌入了函数类型为void(int) 的知识,所以语句&amp;deque&lt;int&gt;::push_back 选择了正确的重载。更简单的语句的问题在于它包含了容器和所包含类型的知识。如果要更改为std::vector,或从int 更改为short,则必须创建所有新类型。使用类型别名,我们可以将所有内容模板化以避免嵌入类型知识:

using func_ptr = void(Cont::*)(typename Cont::const_reference);

我们可以像以前一样做一些简单的事情:

func_ptr<deque<int>> fptr = &deque<int>::push_back;

...或者我们可以在某处引用容器:

vector<short> container;

...在编译时查找其类型,并存储指向其push_back 函数的指针,所有这些都不关心容器是什么:

using container_type = decltype(container);
func_ptr<container_type> fptr2 = &container_type::push_back;

【讨论】:

    【解决方案2】:

    push_back() 采用const T &amp; 参数,如错误消息所述:

    无法转换'void (std::deque::*)(const value_type&) ...

    将您的类型别名更改为:

    typedef void (deque<int>::*func_ptr)(const int &);
    

    【讨论】:

    • @LightnessRacesinOrbit - 在这里使用auto 会出现编译错误,因为函数已重载,并且 auto 不知道与给定函数名关联的重载。
    【解决方案3】:

    您正在尝试做的事情存在更大的问题。允许实现向任何成员函数添加默认参数,因此push_back() 的实际签名可能不同。它甚至可以添加具有相同名称(但签名不同)的其他函数。

    我建议不要使用指向容器成员函数的指针。没有它你通常会更好。

    【讨论】:

    • 我没有否决你,但我怀疑原因是因为响应没有解决 OP 应该如何获得指向此函数的指针的原始问题。很可能,答案加上您对 OP 方法的禁止可能会被单独留下。再说一次,我没有这样做。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    相关资源
    最近更新 更多