【问题标题】:automatic calling custom converter of raw pointers A* <-> B*自动调用原始指针的自定义转换器 A* <-> B*
【发布时间】:2016-09-04 14:08:58
【问题描述】:

是否可以在不同类型的原始指针A*B*之间定义自定义转换器(converter1&lt;T&gt;converter2),
然后在某个类中创建所有函数(fa()fb()
使用合适的转换器(converter1&lt;T&gt;converter2)?

简而言之,我希望程序使用我的自定义函数将A* 转换为B*,反之亦然。
为了我的方便,我希望它会自动执行此操作。

class Manager{
    void fb(B* b){ /** something complex       */ }
    void fa(A* a){ /** different thing complex */ }
    void testCase(){
        A* a=   ... ;  
        fa(a);  
        fb(a);  //automatic convert to B* using "converter2" (wish)
        B* b=   ... ;
        fa(b);  //automatic convert to A* using "converter1" (wish)
        fb(b);
    }
    template<class T> T* converter1(B* b){  //hardcoded, non-static.
        return this->getId<T>(b);   
        //^^^ just an example to show how custom it is,
        //    currently T=A
    }
    B* converter2(A* a){  //hardcoded
        return a->getB();   
        //^^^ just an example to show how custom it is.
    }
}

真实案例有很多A-A1A2A3等。
AB不是相互派生的。

我希望有办法。我想到了指针的构造函数。

【问题讨论】:

  • A 和 B 是相互派生的吗?
  • 不,它们不是相关的类。谢谢,我忘记了,我会添加到问题中。
  • 简答:不,这是不可能的。
  • 但是它们可以通过指针转换??
  • 通过指针转换将一种不相关的类型转换为另一种是未定义的行为。

标签: c++ pointers casting


【解决方案1】:

不,这是不可能的。

指针是内置类型,只存在内置类型之间的内置转换。用户定义的转换仅适用于用户定义的类类型。

您可能想要切换到您自己品牌的智能指针来处理这个问题。

【讨论】:

  • "你自己的智能指针品牌" class APtr{ A* a; },会不会更贵(与我的代码相比)?
  • @javaLover 可能不会。编译器擅长优化这些东西。试试看。
【解决方案2】:

通过引用(或智能指针)更有可能:

struct A {};
struct B {};


A& convert_to_a(A& a) { return a; }
A convert_to_a(B const& b) { 
    // makes a new A from a B
    return A(); 
}

B& convert_to_b(B& b) { return b; }
B convert_to_b(A const& a) { return B(); }


struct Manager
{
  template<class T>
  void fa(T&& t) { 
    auto&& a = convert_to_a(t); 
    // do something with a
    (void)a;
  }

  template<class T>
    void fb(T&& t) { 
    auto&& b = convert_to_b(t); 
    // do something with b
    (void)b;
  }

};

int main()
{
  A a;
  B b;

  Manager m;

  m.fa(a);
  m.fb(a);
  m.fa(b);
  m.fb(b); 
}

【讨论】:

    【解决方案3】:

    不可能如你所愿。
    无论如何,您可以使用一个包罗万象的函数和一堆特征来模拟它。
    它遵循一个最小的工作示例:

    #include<iostream>
    
    struct A {};
    struct B {};
    
    template<typename T>
    A* ToAConverter(T*) = delete;
    
    template<>
    A* ToAConverter<B>(B *b) {
        // just an example
        return new A;
    }
    
    struct Manager{
        void fa(A* a){ std::cout << "fa" << std::endl; }
    
        template<typename T>
        void fa(T *t) {
            std::cout << "convert and forward" << std::endl;
            fa(ToAConverter<T>(t));
        }
    
        void testCase(){
            A *a = new A;  
            fa(a);  
            B *b = new B;
            fa(b); 
        }
    };
    
    int main() {
        Manager m;
        m.testCase();
    }
    

    如果您尚未为特定类型定义 converter,您将收到编译时错误。
    如您所见,调用fa 时不再显式调用转换器。

    【讨论】:

      猜你喜欢
      • 2019-06-22
      • 1970-01-01
      • 1970-01-01
      • 2019-08-21
      • 1970-01-01
      • 1970-01-01
      • 2012-06-26
      • 2017-05-16
      • 1970-01-01
      相关资源
      最近更新 更多