【问题标题】:Pointer-to-Member invalid conversion from ‘Derived X::*’ to ‘Base X::*’Pointer-to-Member 从“Derived X::*”到“Base X::*”的无效转换
【发布时间】:2016-01-04 18:48:28
【问题描述】:

我想知道为什么在指针到成员转换的情况下,从派生类指针到基类指针的简单转换会失败。例如,

    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;
                        ^

【问题讨论】:

    标签: c++ pointers pointer-to-member


    【解决方案1】:

    因为两者之间没有任何有意义的转换。

    您正在尝试将“指向 B 类中的事物的指针”分配给“指向 A 类中的事物的指针”类型的对象。

    这两个类之间的继承关系不相关——A 类根本不包含你想要指向的东西。类型系统正在发挥作用。

    你必须找到一些其他的方式来做你想做的任何事情。不幸的是,你没有说那是什么,所以我无法提供进一步的帮助!

    【讨论】:

    • 并非如此。 OP 并不是试图将“指向 B 类中的事物的指针”分配给“指向 A 类中的事物的指针”类型的对象。两个指针都是指向“X 类中的事物”的指针。只是类型不同。
    • 我不确定我是否理解您的回答。我正在尝试将DerivedX 中的指针转换为Base
    • @AndreiKouznetsov,看看我的回答。它们是不可转换的,因为它们是指向成员的指针。
    • @AndreiKouznetsov:不,你不是
    【解决方案2】:

    这是正确的。使用指向成员的指针时,不能使用指向基的指针来标识派生类。指向成员的指针不是指针! :)

    【讨论】:

      【解决方案3】:
      Base X::*
      

      表示指向 X 的 Base 类型成员的指针。

      不一样

      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;
      }
      

      下面是如何使用指向成员的示例:

      #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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-12
        • 2021-02-04
        • 2022-10-23
        • 2018-12-15
        • 1970-01-01
        相关资源
        最近更新 更多