标签: pointer-to-member

如何获取重载成员函数的地址?

我正在尝试获取指向特定版本的重载成员函数的指针.这是一个例子:

class C
{
  bool f(int) { ... }
  bool f(double) { ... }

  bool example()
  {
    // I want to get the "double" version.
    typedef bool (C::*MemberFunctionType)(double);
    MemberFunctionType pointer = &C::f;   // <- Visual C++ complains
  }
};
Run Code Online (Sandbox Code Playgroud)

错误消息是"错误C2440:'初始化':无法从'重载函数'转换为'MemberFunctionType'"

如果f没有重载,这可以工作,但不是在上面的例子中.有什么建议吗?

编辑

请注意,上面的代码并没有反映我的现实世界问题,那就是我忘记了一个"const" - 这就是被接受的答案所指出的.不过,我会留下问题,因为我觉得问题可能发生在其他人身上.

c++ overloading pointer-to-member

18
推荐指数
1
解决办法
1万
查看次数

std算法,指向成员的指针作为比较器/"键"

我经常发现自己使用std::sort,std::max_element以及与简单地调用成员函数拉姆达等等

std::vector<MyType> vec;
// populate...
auto m = std::max_element(std::begin(vec), std::end(vec),
    [](const MyType& a, const MyType& b) { return a.val() < b.val()})
Run Code Online (Sandbox Code Playgroud)

这感觉就像是浪费角色和失去清晰度.我知道我可以编写另一个函数/可调用函数并将函数指针/可调用对象传递给这些算法函数,但我经常需要在程序中执行此类操作,并且它不会让我感觉良好解决问题的方法.我想做什么,理想情况是说:

auto m = std::max_element(std::begin(vec), std::end(vec), &MyType::val);
Run Code Online (Sandbox Code Playgroud)

并按对象对对象进行排序val().我有什么部分stdlib可以帮助我解决这个问题吗?或另一种简单的方法吗?我想尽可能明显地进行排序或搜索.

我知道这&MyType::val还不够,我正在寻找可以包装它的东西,或提供类似的功能而不会妨碍其含义.

c++ algorithm pointer-to-member c++11

18
推荐指数
1
解决办法
458
查看次数

为什么auto_ptr不支持op - >*()

auto_ptr(shared_ptr也是如此)尽量使它们尽可能透明; 也就是说,理想情况下,您不应该区分是否使用auto_ptr或指向对象的实际指针.考虑:

class MyClass
{
public:
    void foo() {  }
};

MyClass* p = new MyClass;
auto_ptr<MyClass> ap(new MyClassp);

p->foo();       // No notational difference in using real
ap->foo();      // pointers and auto_ptrs
Run Code Online (Sandbox Code Playgroud)

当您尝试通过指向成员的指针调用成员函数时,存在差异,因为auto_ptr显然不实现op - >*():

void (MyClass::*memfun)() = &MyClass::foo;

(p->*memfun)();         // OK
(ap->*memfun)();        // Error op->*() missing
(ap.get()->*memfun)();  // OK
Run Code Online (Sandbox Code Playgroud)

为什么auto_ptr中不支持op - >*()以及如何实现它(我已经实验了一段时间,但最终放弃了).

c++ operator-overloading pointer-to-member

17
推荐指数
2
解决办法
321
查看次数

指向折叠表达式中成员函数的指针

这段代码多次调用&foo :: next

struct foo
{
    foo& next()
    {
        return *this;
    }
};

template<typename Obj>
void tmp_funct_1(Obj& obj)
{}

template<typename Obj, typename Func, typename... Other>
void tmp_funct_1(Obj& obj, Func func, Other... other)
{
    tmp_funct_1((obj.*func)(), other...);
}
Run Code Online (Sandbox Code Playgroud)

现在我想用一个折叠表达式替换递归调用

例:

template<typename Obj, typename... Func>
void tmp_funct_2(Obj& obj, Func... func)
{
    (obj .* ... .* func());
}
Run Code Online (Sandbox Code Playgroud)

它不会编译,因为指向成员调用的指针的正确语法是

(obj.*func)()
Run Code Online (Sandbox Code Playgroud)

如何使用模板折叠表达式获得相同的结果?谢谢!

int main()
{
    foo obj;
    auto to_foo = &foo::next;

    tmp_funct_1(obj, to_foo, to_foo, to_foo);
//  tmp_funct_2(obj, to_foo, to_foo, to_foo);
}
Run Code Online (Sandbox Code Playgroud)

c++ pointer-to-member fold-expression c++17

17
推荐指数
1
解决办法
635
查看次数

Crazy C++模板 - 用于访问类的各个属性的模板

我是一名新手C++程序员,但我认为我对C++知之甚多,直到今天我在工作中遇到这样的代码并且无法理解它是如何工作的.

class Object
{
};

template <
        class PropObject,
        class PropType, 
        PropType PropObject::* Prop
        >
class PropReader
{
public:
    void print(Object& o)
    {
        PropObject& po = static_cast<PropObject &>(o);
        PropType& t = po.*Prop;

        cout << t << "\n";
    }
};

class Student : public Object
{
public:
    int age;
    int grade;
};

int _tmain(int argc, _TCHAR* argv[])
{   
    Student s;
    s.age = 10;
    s.grade = 5;

    PropReader<Student, int, &Student::age> r;
    PropReader<Student, int, &Student::grade> r2;

    r.print(s);
    r2.print(s);
}
Run Code Online (Sandbox Code Playgroud)

我觉得我有点高层次的理解.但是PropType PropObject::* Prop …

c++ templates pointer-to-member

15
推荐指数
1
解决办法
2909
查看次数

在void*和指向成员函数的指针之间进行转换

我目前正在使用GCC 4.4,而且我之间void*有一个令人头痛的问题,并且指向成员函数.我正在尝试编写一个易于使用的库,用于将C++对象绑定到Lua解释器,如下所示:

LuaObject<Foo> lobj = registerObject(L, "foo", fooObject);
lobj.addField(L, "bar", &Foo::bar);
Run Code Online (Sandbox Code Playgroud)

我已经完成了大部分工作,除了以下函数(特定于某个函数签名,直到我有机会对其进行概括):

template <class T>
int call_int_function(lua_State *L) 
{
    // this next line is problematic
    void (T::*method)(int, int) = reinterpret_cast<void (T::*)(int, int)>(lua_touserdata(L, lua_upvalueindex(1)));
    T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1));

    (obj->*method)(lua_tointeger(L, 2), lua_tointeger(L, 3));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

对于那些不熟悉Lua的人,lua_touserdata(L, lua_upvalueindex(1))获取与闭包相关的第一个值(在这种情况下,它是指向成员函数的指针)并将其作为a返回void*.海湾合作委员会抱怨说void*- > void (T::*)(int, int)是无效的演员.关于如何解决这个问题的任何想法?

c++ lua pointers pointer-to-member

13
推荐指数
3
解决办法
2万
查看次数

如何在C++中打印成员函数地址

它看起来像std::cout无法打印成员函数的地址,例如:

#include <iostream>

using std::cout;
using std::endl;

class TestClass
{
  void MyFunc(void);

public:
  void PrintMyFuncAddress(void);
};

void TestClass::MyFunc(void)
{
  return;
}

void TestClass::PrintMyFuncAddress(void)
{
  printf("%p\n", &TestClass::MyFunc);
  cout << &TestClass::MyFunc << endl;
}

int main(void)
{
  TestClass a;

  a.PrintMyFuncAddress();

  return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

结果是这样的:

003111DB
1
Run Code Online (Sandbox Code Playgroud)

如何MyFunc使用打印地址std::cout

c++ pointers function-pointers pointer-to-member

13
推荐指数
4
解决办法
1万
查看次数

为对象存储成员函数的位置在哪里?

我正在尝试用C++来理解类/结构及其各自的对象是如何在内存中布局的,我理解类/结构的每个字段都是它们各自对象的偏移量(所以我可以有一个成员变量指针).

我不明白为什么,即使我可以有成员函数指针,下面的代码也不起作用:

struct mystruct
{
    void function()
    {
        cout << "hello world";
    }
    int c;
};

int main() 
{ 
    unsigned int offset_from_start_structure = (unsigned int)(&((mystruct*)0)->c);
    unsigned int offset_from_start_structure2 = (unsigned int)(&((mystruct*)0)->function); // ERROR - error C2276: '&' : illegal operation on bound member function expression



    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么这条线

unsigned int offset_from_start_structure = (unsigned int)(&((mystruct*)0)->c);
Run Code Online (Sandbox Code Playgroud)

编译并返回结构和行开头的"c"字段的偏移量

unsigned int offset_from_start_structure2 = (unsigned int)(&((mystruct*)0)->function);
Run Code Online (Sandbox Code Playgroud)

甚至不编译?

c++ memory function-pointers pointer-to-member

12
推荐指数
2
解决办法
6775
查看次数

通过指针调用base函数的qualified-id

如果我foo()首先在基类中定义了虚函数B,然后在派生类中重写D,那么如何B::foo以指向成员函数的方式存储地址,以便在调用它时,调用将表现为一个有资格的id(如pd->B::foo())?

例:

struct B {
    virtual int foo() { return 1; }
};

struct D: public B {
    virtual int foo() { return 2; }
};

int main(int argc, char * argv[]) {
    D* pd = new D();
    int (B::*pf)() = &B::foo;
    int r = (pd->*pf)();
    return 0; 
}
Run Code Online (Sandbox Code Playgroud)

这会打电话D::foo().我可以初始化pf,即使动态类型是一个覆盖的类,它(pd->*pf)()也会调用吗?B::foo()pdfoo()

(在任何人问之前,我真的不想这样做,我只是好奇,如果可能的话.)

c++ pointer-to-member

11
推荐指数
1
解决办法
218
查看次数

为什么对于同一结构的不同成员,指向成员的指针的值总是相同的?

我有以下代码:

#include <iostream>
#include <string>

using namespace std;

struct foo_s {
    string a;
    string b;
    string c;
};

void print_field(foo_s* foo, string foo_s::* field) {
    cout << "field: " << field << " - " << foo->*field << endl;
}

int main() {
   foo_s my_foo = {
       "a",
       "b",
       "c",
   };

   print_field(&my_foo, &foo_s::a);
   print_field(&my_foo, &foo_s::b);
   print_field(&my_foo, &foo_s::c);

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

它的输出是:

field: 1 - a                                                                                                                                                                                                              
field: 1 - b                                                                                                                                                                                                              
field: 1 - c  
Run Code Online (Sandbox Code Playgroud)

我在理解print_field()函数中发生的事情的细节时遇到了一些麻烦.即:

  1. 这是什么类型的field?我想是的pointer-to-string-foo_s-member …

c++ pointer-to-member language-lawyer

11
推荐指数
2
解决办法
482
查看次数