给出一个示例类:
class Fred
{
public:
Fred() 
{
    func = &Fred::fa;
}
void run()
{
     int foo, bar;
     *func(foo,bar);
}
double fa(int x, int y);
double fb(int x, int y);
private:
double (Fred::*func)(int x, int y);
};
我在通过指针"*func(foo,bar)"调用成员函数的行中遇到编译器错误,说:"术语不会计算为带有2个参数的函数".我究竟做错了什么?
演示:
#include<iostream>
struct A { int i = 10; };
struct B : A { };
int main(){
    std::cout << "decltype(&B::i) == int A::* ? " << std::boolalpha
              << std::is_same<decltype(&B::i), int A::*>::value << '\n';    //#1
    A a;
    std::cout << a.*(&A::i) << '\n';
    std::cout << "decltype(&B::i) == int B::* ? "
              << std::is_same<decltype(&B::i), int B::*>::value << '\n';    //#2
    B b;
    std::cout << b.*(&B::i) << '\n';
}
代码打印
decltype(&B::i) == int A::* ? true
10
decltype(&B::i) == int B::* ? false …$ 4.11/2州 -
类型为" cv
B类型成员的指针"的rvalue ,其中是类类型,可以转换为类型为"指向cv类型 成员的指针"的rvalue ,其中是派生类(第10节).如果不可访问(第11条),模糊(10.2)或虚拟(10.1)基类 ,则需要进行此转换的程序是不正确的.TBDTDBBD
我的问题是为什么我们有限制B不是虚拟基类D?
假设我们有一个指向类的字段指向类的成员.我们还有一个指向该类的特定实例中的特定字段的指针.例如,我们可能会有这样的事情:
class A {
     B inner_object;
}
A* myA = /* ... */
B* ptr = &myA->inner_object;
B A::* memPtr = &A::inner_object;
有没有办法使用ptr和memPtr恢复myA?也就是说,如果我们没有已经有了一个明确的指针myA,我们可以做一个出来的ptr和memPtr?
在工作中,我正在尝试一些,以反映我们的代码库.基本上我想要实现的是捕获数据成员的初始化器类型中的数据成员的指针:
template<class Class, int Class::*dataMember>
struct Reflect
{
  operator int() {return 0;}
};
class Foo
{
public:
  int bar = Reflect<Foo, &Foo::bar>{};
};
虽然clang 3.4.1(http://gcc.godbolt.org/)和Intel C++ XE 14.0能够编译这段代码,但在使用MSVC12时,我收到以下错误消息:
错误C2065:'bar':未声明的标识符
错误C2975:'dataMember':'Reflect'的模板参数无效,是预期的编译时常量表达式
此外,gcc 4.9.2似乎也有问题:http://ideone.com/ZUVOMO.
所以我的问题是:
我试图理解这个程序中引发的错误的一致性:
#include <iostream>
class A{
public:
    void test();
    int x = 10;
};
void A::test(){
    std::cout << x << std::endl; //(1)
    std::cout << A::x << std::endl; //(2)
    int* p = &x;
    //int* q = &A::x; //error: cannot convert 'int A::*' to 'int*' in initialization| //(3)
}
int main(){
    const int A::* a = &A::x; //(4)
    A b;
    b.test();
}
输出是10 10.我标记了该计划的4个点,但(3)是我最关心的问题:
x 通常从成员函数内部获取.x使用范围运算符获取对象的对象,x并返回对象的左值.A::x返回int(2)中的左值,为什么然后&A::x返回不是int*,而是返回int A::* …有结构
struct Person{
    Person( int i , int g):id(i),age(g){};
    int id;
    int age;
};
我可以通过将指向成员数据的指针作为参数传递给函数来动态返回成员数据.例如
int extract( Person * p , int Person::* param)
{   
    return p ->*param;
}
并使用
Person *p = new Person (10 , 20 );
cout << extract(p , &Person::id )<< endl;
但我的问题是,为什么这有效?我们传递&Person::id基本的内存,但是Person是一个违背定义的r值.
我感谢所有对我可能对主题的误解的解释/澄清.谢谢.
我过去总是将代码复制并粘贴到cppinsights中,以查看代码中的哪些位置由编译器隐式执行对话。但该站点上未显示指向成员的指针标准转换。
当看到这个问题的答案时,我变得更加困惑:向下转型指向成员的指针会导致未定义的行为。我认为这个问题本身是错误的,因为据我所知,根据[conv.mem]/2可以安全地向下转换指向成员的指针;但除非应用[expr.static.cast]/12 ,否则无法安全地向上转换。这个问题有以下代码(已编辑):
struct B { int a; };
struct D1 : B {};
struct D2 : B { int b; };
void f() 
{
    int D1::*ptr = &B::a;  // #1
    int D1::*ptr = &D2::a; // #2
    int B::*ptr = &D1::a;  // #3
    int D1::*ptr = &D2::b; // #4
}
我的困惑只是因为我不知道到底ptr指向什么?到封闭对象本身的成员?或者封闭对象的子对象的成员?
因此,在在这里发布任何问题之前,我求助于一位 C++ 程序员(实际上是我退休的老师)来帮助我并解释上述隐式对话(如果有的话)。简而言之,这就是我得到的:
#1-这里,初始化器是指定指向成员的指针的纯右值B::a。并且由于D1具有B未命名的子对象,ptr因此可以指向a …
我从c ++练习册中复制了这个程序.幕后发生了什么?
预期的产出是:
sum = 30 sum = 70
#include<iostream>
using namespace std;
class M
{
    int x;
    int y;
public:
    void set_xy(int a, int b)
    {
        x=a;
        y=b;
    }
    friend int sum(M m);
};
int sum (M m);
//so far so good, problem begins from here. what's happening after here?
{                               
    int M ::*px = &M ::x;
    int M ::*py = &M ::y;
    M *pm =&m;
    int s= m.*px+ pm->*py;
    return s;
}
int main()
{
    M n;
    void …c++ ×10
c++11 ×3
base-class ×1
dereference ×1
initializer ×1
parent ×1
pointers ×1
rvalue ×1
templates ×1
virtual ×1