我正在尝试获取指向特定版本的重载成员函数的指针.这是一个例子:
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" - 这就是被接受的答案所指出的.不过,我会留下问题,因为我觉得问题可能发生在其他人身上.
我经常发现自己使用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还不够,我正在寻找可以包装它的东西,或提供类似的功能而不会妨碍其含义.
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 - >*()以及如何实现它(我已经实验了一段时间,但最终放弃了).
这段代码多次调用&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++程序员,但我认为我对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 …
我目前正在使用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)是无效的演员.关于如何解决这个问题的任何想法?
它看起来像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++来理解类/结构及其各自的对象是如何在内存中布局的,我理解类/结构的每个字段都是它们各自对象的偏移量(所以我可以有一个成员变量指针).
我不明白为什么,即使我可以有成员函数指针,下面的代码也不起作用:
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)
甚至不编译?
如果我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()
(在任何人问之前,我真的不想这样做,我只是好奇,如果可能的话.)
我有以下代码:
#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()函数中发生的事情的细节时遇到了一些麻烦.即:
field?我想是的pointer-to-string-foo_s-member …