Pertanyaan Kesalahan dengan alamat fungsi anggota yang disisipkan


Saya menemukan sesuatu yang menarik. Pesan kesalahan mengatakan itu semua. Apa alasan di balik tidak mengizinkan tanda kurung saat mengambil alamat dari fungsi anggota non-statis? Saya mengkompilasinya pada gcc 4.3.4.

#include <iostream>

class myfoo{
    public:
     int foo(int number){
         return (number*10);
     }
};

int main (int argc, char * const argv[]) {

    int (myfoo::*fPtr)(int) = NULL;

    fPtr = &(myfoo::foo);  // main.cpp:14

    return 0;

}

Kesalahan: main.cpp: 14: error: ISO C ++ melarang mengambil alamat dari fungsi anggota non-statik yang tidak memenuhi syarat atau yang dikecualikan untuk membentuk pointer ke fungsi anggota. Katakan '& myfoo :: foo'


32
2017-08-20 19:39


asal


Jawaban:


Dari pesan kesalahan, sepertinya Anda tidak diizinkan untuk mengambil alamat dari ekspresi yang disisipkan. Ini menunjukkan bahwa Anda menulis ulang

fPtr = &(myfoo::foo);  // main.cpp:14

untuk

fPtr = &myfoo::foo;

Hal ini disebabkan sebagian dari spesifikasi (§5.3.1 / 3) yang berbunyi

Penunjuk ke anggota hanya terbentuk ketika eksplisit & digunakan dan operandnya adalah id-kualifikasi tidak diapit dalam tanda kurung [...]

(Penekanan saya). Saya tidak yakin mengapa ini adalah aturan (dan saya tidak benar-benar tahu ini sampai sekarang), tetapi ini tampaknya menjadi apa yang kompilator keluhkan.

Semoga ini membantu!


25
2017-08-20 19:44



Bayangkan kode ini:

struct B { int data; };
struct C { int data; };

struct A : B, C {
  void f() {
    // error: converting "int B::*" to "int*" ?
    int *bData = &B::data;

    // OK: a normal pointer
    int *bData = &(B::data);
  }
};

Tanpa trik dengan tanda kurung, Anda tidak akan dapat mengambil penunjuk langsung ke anggota data B (Anda akan membutuhkan pemain dan permainan kelas dasar dengan this - tidak baik).


Dari ARM:

Perhatikan bahwa alamat-operator harus secara eksplisit digunakan untuk mendapatkan penunjuk ke anggota; tidak ada konversi implisit ... Seandainya ada, kita akan memiliki ambiguitas dalam konteks fungsi anggota ... Misalnya,

void B::f() {
    int B::* p = &B::i; // OK
    p = B::i; // error: B::i is an int
    p = &i; // error: '&i'means '&this->i' which is an 'int*'

    int *q = &i; // OK
    q = B::i; // error: 'B::i is an int
    q = &B::i; // error: '&B::i' is an 'int B::*'
}

IS hanya menyimpan konsep pra-Standar ini dan secara eksplisit menyebutkan bahwa tanda kurung membuatnya sehingga Anda tidak mendapatkan penunjuk ke anggota.


14
2017-08-21 13:42