从“Derived X::*”到“Base X::*”的指向成员的无效转换
Pointer-to-Member invalid conversion from ‘Derived X::*’ to ‘Base X::*’
我想知道为什么在指针到成员转换的情况下,从派生 class 指针到基 class 指针的简单转换会失败。例如,
struct Base {};
struct Derived: public Base {};
struct X {
Derived field;
};
int main(int argc, char *argv[]) {
Base X::* ptr1 = &X::field;
return 0;
}
报错:
$ g++ t.cc
t.cc: In function ‘int main(int, char**)’:
t.cc:9:24: error: invalid conversion from ‘Derived X::*’ to ‘Base X::*’ [-fpermissive]
Base X::* ptr1 = &X::field;
^
因为两者之间没有有意义的转换。
您正在尝试将 "pointer to a thing in Class B" 分配给类型为 "pointer to a thing in Class A" 的对象。
两者之间的继承关系类在这里不相关——ClassA根本不包含你要指向的东西。类型系统正在发挥作用。
你必须找到其他方法来做你想做的事。不幸的是你没有说那是什么,所以我无法提供进一步的帮助!
这是正确的。使用 pointer-to-member 时,不能使用指向基的指针来标识派生的 class。 Pointers-to-members 不是指针! :)
Base X::*
表示指向具有 Base 类型的 X 成员的指针。
与
不一样
Base*
没有转化
Base*
到
Base X::*
因此没有来自
的转换
Derived*
到
Base X::*
同样Base X::*
和Derived X::*
之间也没有转换
示例:
#include <iostream>
using namespace std;
class Base
{
};
class Derived : public Base
{
};
class X {
public:
Derived field1;
Base field2;
};
int main() {
Base X::* ptr1 = &X::field1; // Derived X::* to Base X::* OK ?
Derived X::* ptr2 = &X::field2; // Base X::* to Derived X::* OK ?
return 0;
}
这将导致
prog.cpp:20:28: error: invalid conversion from 'Derived X::*' to 'Base X::*' [-fpermissive]
Base X::* ptr1 = &X::field1;
^
prog.cpp:21:31: error: invalid conversion from 'Base X::*' to 'Derived X::*' [-fpermissive]
Derived X::* ptr2 = &X::field2;
所以为了编译,需要:
int main() {
Derived X::* ptr1 = &X::field1;
Base X::* ptr2 = &X::field2;
return 0;
}
下面是如何使用 pointer-to-member 的示例:
#include <iostream>
#include <vector>
using namespace std;
class Base
{
public:
Base(int g1) : g(g1) {}
int g;
};
class Derived : public Base
{
public:
Derived(int d) : Base(d) {}
};
class X {
public:
X(int f1, int f2) : field1(f1), field2(f2) {}
Derived field1;
Derived field2;
};
void foo(vector<X>& vx, Derived X::*d)
{
cout << "foo" << endl;
for (auto& x : vx)
{
cout << (x.*d).g << endl;
}
}
int main() {
vector<X> vx {{5, 10}, {50, 100}};
foo(vx, &X::field1); // Print field1.g of all elements in vector vx
foo(vx, &X::field2); // Print field2.g of all elements in vector vx
return 0;
}
这将输出:
foo
5
50
foo
10
100
我想知道为什么在指针到成员转换的情况下,从派生 class 指针到基 class 指针的简单转换会失败。例如,
struct Base {};
struct Derived: public Base {};
struct X {
Derived field;
};
int main(int argc, char *argv[]) {
Base X::* ptr1 = &X::field;
return 0;
}
报错:
$ g++ t.cc
t.cc: In function ‘int main(int, char**)’:
t.cc:9:24: error: invalid conversion from ‘Derived X::*’ to ‘Base X::*’ [-fpermissive]
Base X::* ptr1 = &X::field;
^
因为两者之间没有有意义的转换。
您正在尝试将 "pointer to a thing in Class B" 分配给类型为 "pointer to a thing in Class A" 的对象。
两者之间的继承关系类在这里不相关——ClassA根本不包含你要指向的东西。类型系统正在发挥作用。
你必须找到其他方法来做你想做的事。不幸的是你没有说那是什么,所以我无法提供进一步的帮助!
这是正确的。使用 pointer-to-member 时,不能使用指向基的指针来标识派生的 class。 Pointers-to-members 不是指针! :)
Base X::*
表示指向具有 Base 类型的 X 成员的指针。
与
不一样Base*
没有转化
Base*
到
Base X::*
因此没有来自
的转换Derived*
到
Base X::*
同样Base X::*
和Derived X::*
示例:
#include <iostream>
using namespace std;
class Base
{
};
class Derived : public Base
{
};
class X {
public:
Derived field1;
Base field2;
};
int main() {
Base X::* ptr1 = &X::field1; // Derived X::* to Base X::* OK ?
Derived X::* ptr2 = &X::field2; // Base X::* to Derived X::* OK ?
return 0;
}
这将导致
prog.cpp:20:28: error: invalid conversion from 'Derived X::*' to 'Base X::*' [-fpermissive]
Base X::* ptr1 = &X::field1;
^
prog.cpp:21:31: error: invalid conversion from 'Base X::*' to 'Derived X::*' [-fpermissive]
Derived X::* ptr2 = &X::field2;
所以为了编译,需要:
int main() {
Derived X::* ptr1 = &X::field1;
Base X::* ptr2 = &X::field2;
return 0;
}
下面是如何使用 pointer-to-member 的示例:
#include <iostream>
#include <vector>
using namespace std;
class Base
{
public:
Base(int g1) : g(g1) {}
int g;
};
class Derived : public Base
{
public:
Derived(int d) : Base(d) {}
};
class X {
public:
X(int f1, int f2) : field1(f1), field2(f2) {}
Derived field1;
Derived field2;
};
void foo(vector<X>& vx, Derived X::*d)
{
cout << "foo" << endl;
for (auto& x : vx)
{
cout << (x.*d).g << endl;
}
}
int main() {
vector<X> vx {{5, 10}, {50, 100}};
foo(vx, &X::field1); // Print field1.g of all elements in vector vx
foo(vx, &X::field2); // Print field2.g of all elements in vector vx
return 0;
}
这将输出:
foo
5
50
foo
10
100