我想撰写成员指针.基本上我有一个不同成员的主类.如何为主类创建一个指向该类成员的成员指针.我希望下面的代码解释我正在尝试做什么:
struct SubUnit
{
int value;
};
struct Unit
{
SubUnit sub_unit;
};
void Test()
{
SubUnit Unit::* ptr1 = &Unit::sub_unit; // WORKING
int Unit::* ptr2 = &Unit::sub_unit::value; // NOT WORKING !
}
Run Code Online (Sandbox Code Playgroud) 我知道这在C++ 03中是不可能的,但我希望有一些新的巫术允许我这样做.见下文:
template <class T>
struct Binder
{
template<typename FT, FT T::*PtrTomember>
void AddMatch();
};
struct TestType
{
int i;
};
int main(int argc, char** argv)
{
Binder<TestType> b;
b.AddMatch<int,&TestType::i>(); //I have to do this now
b.AddMatch<&TestType::i>(); //I'd like to be able to do this (i.e. infer field type)
}
Run Code Online (Sandbox Code Playgroud)
在C++ 11中有没有办法做到这一点?decltype会有帮助吗?
**更新:使用Vlad的例子我认为这样的事情会起作用(警告:我没有编译,因为我正在构建具有decltype支持的编译器)
template <class T>
struct Binder
{
template<typename MP, FT ft = decltype(MP)>
void AddMatch()
{
//static_assert to make sure MP is a member pointer of T
} …Run Code Online (Sandbox Code Playgroud) 最近我尝试运行以下代码。
#include <iostream>
class Base
{
public:
virtual void func()
{
std::cout<<"Base called"<<std::endl;
}
};
class Derived: public Base
{
public:
virtual void func() override
{
std::cout<<"Derived called"<<std::endl;
}
};
int main()
{
void (Base::*func_ptr)()=&Base::func; //Yes, the syntax is very beautiful.
Base* bptr=new Derived();
(bptr->*func_ptr)();
}
Run Code Online (Sandbox Code Playgroud)
我的预期输出是Base called. 然而,输出是
Derived called
Run Code Online (Sandbox Code Playgroud)
这让我感到惊讶,因为根据我的理解,func_ptr应该只能看到Base成员(因为据我所知,func_ptr不是通过 访问成员函数_vptr,而是访问函数地址本身。
我想知道,在这种情况下虚拟调度是如何发生的(如何访问虚拟表),以及这种行为在 C++ 标准中定义的位置(我搜索过但找不到任何东西)?
template<class T, typename U> ptrdiff_t foo(T U::* m)
{
// return offset
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如何获得字段'm'的偏移量?我更喜欢使用am编译时表达式.
在此先感谢您的帮助.最好的祝福
以下代码产生编译时错误:
'
base::print':无法访问类中声明的私有成员'base_der'
但是,我已public在派生类中创建了该成员.为什么这不起作用?
#include <iostream>
using namespace std;
class base
{
public:
int i;
void print(int i)
{
printf("base i\n");
}
};
class base_der : private base
{
public:
using base::print;
};
int main()
{
// This works:
base_der cls;
cls.print(10);
// This doesn't:
void (base_der::* print)(int);
print = &base_der::print; // Compile error here
}
Run Code Online (Sandbox Code Playgroud) c++ member-function-pointers member-pointers implicit-conversion private-inheritance
//#define NOT_WORKS
#define HOW(X) 0
struct A {
};
struct B {
A a;
};
struct C {
B b;
};
int main(int argc, char **argv) {
A B::*ba = &B::a; // ba is a pointer to B::a member
B C::*cb = &C::b; // cb is a pointer to C::b member
#ifdef NOT_WORKS
{ A C::*ca = &C::b::a; } // error: Symbol a could not be resolved / error: ‘C::b’ is not a class or namespace
{ A C::*ca = …Run Code Online (Sandbox Code Playgroud) 假设我有这个代码:
#include <iostream>
struct Mine
{
int a;
int b;
};
int main()
{
int Mine::* memberPointerA = &Mine::a;
int Mine::* memberPointerB = &Mine::b;
std::cout << memberPointerA;
std::cout << "\n";
std::cout << memberPointerB;
}
Run Code Online (Sandbox Code Playgroud)
当我使用Microsoft Visual C++(2015)运行它时
我得到以下输出
1
1
Run Code Online (Sandbox Code Playgroud)
我期望的输出更像是这样的:
1
2
Run Code Online (Sandbox Code Playgroud)
所以这引出了一个问题:这个成员指针的打印是否定义了行为?
我有关于成员指针的问题.以下代码无法使用Oracle Solaris Studio 12.2的CC和cygwin GCC 4.3.4进行编译,但与Microsoft Visual C++ 2010一起使用:
struct A {
int x;
};
struct B : public A {
};
template<typename T> class Bar {
public:
template<typename M> void foo(M T::*p);
};
int main(int, char *[]) {
Bar<B> bbar;
bbar.foo(&B::x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在倒数第二行,上面提到的两个编译器都找不到匹配项Bar<B>::foo(int A::*).我写了一个简单的测试来确认表达式的类型&B::x实际上是int A::*:
// ...
static void foo(int A::*p) {
std::cout << "A" << std::endl;
}
static void foo(int B::*p) {
std::cout << "B" << std::endl;
}
int main(int, …Run Code Online (Sandbox Code Playgroud) 我可以创建和参考相对指针为结构用C++成员使用::*,.*和->*语法,如:
char* fstab_t::*field = &fstab_t::fs_vfstype;
my_fstab.*field = ...
Run Code Online (Sandbox Code Playgroud)
在Haskell中,我可以轻松地为记录getter创建临时标签,例如:
(idxF_s,idxL_s) = swap_by_sign sgn (idxF,idxL) ;
Run Code Online (Sandbox Code Playgroud)
Afaik,然后我不能使用这些getter更新记录,如:
a { idxF_s = idxL_s b }
Run Code Online (Sandbox Code Playgroud)
是否有一种简单的方法可以在不编码每个记录设置器的情况下执行此操作
include <stdio.h>
class Base
{
protected:
int foo;
int get_foo() { return foo; }
};
class Derived : public Base
{
public:
void bar()
{
int Base::* i = &Base::foo;
this->*i = 7;
printf("foo is %d\n", get_foo());
}
};
int main()
{
Derived d;
d.bar();
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么我的派生类型不能指向基类的受保护成员.它有权访问该成员.它可以调用类似范围的函数.为什么它不能成为成员指针?我正在使用gcc 4.1.2,我收到此错误:
test.cc: In member function ‘void Derived::bar()’:
test.cc:6: error: ‘int Base::foo’ is protected
test.cc:15: error: within this context
Run Code Online (Sandbox Code Playgroud) member-pointers ×10
c++ ×9
templates ×2
c++11 ×1
composition ×1
cout ×1
decltype ×1
haskell ×1