C++ C++;专门化、类型\或仅类型ID

C++ C++;专门化、类型\或仅类型ID,c++,types,specialization,C++,Types,Specialization,我想知道在我的情况下使用什么更好,为什么。首先,我听说使用RTTI(typeid)是不好的。谁能解释为什么?如果我确切地知道类型,那么在运行时比较它们有什么不对?此外,有没有关于如何使用boost::type_的示例?我没有在强大的谷歌搜索中发现任何东西:)我的另一个解决方案是专门化,但我需要专门化至少9种新方法。以下是我需要的一个示例: 我有这门课 template<typename A, typename B, typename C> class CFoo {

我想知道在我的情况下使用什么更好,为什么。首先,我听说使用RTTI(typeid)是不好的。谁能解释为什么?如果我确切地知道类型,那么在运行时比较它们有什么不对?此外,有没有关于如何使用boost::type_的示例?我没有在强大的谷歌搜索中发现任何东西:)我的另一个解决方案是专门化,但我需要专门化至少9种新方法。以下是我需要的一个示例:

我有这门课

  template<typename A, typename B, typename C>
  class CFoo
  {
     void foo()
     {
       // Some chunk of code depends on old A type
     }

  }
那么最好的解决方案是什么?我不想对所有的A、B、C进行专门化,因为每个类型都有3个专门化,所以我将得到9个方法或只是这个类型ID检查。

这很糟糕,因为

  • A、 B和C在编译时是已知的,但您使用的是运行时机制。如果调用typeid,编译器将确保将元数据包含到对象文件中
  • 如果您用使用CSomeClass接口的实际代码替换“执行与类型相关的代码块”,您将看到在出现错误的情况下无法编译代码=CSomeClass和具有不兼容接口的。编译器仍然尝试翻译代码,即使它从未运行过。(见下面的示例)
  • 您通常会将代码分解成单独的函数模板或可以专门化的类的静态成员函数

    坏的:

    模板
    void foo(T x){
    if(typeid(T)=typeid(int*)){
    *x=23;//实例化错误:无法取消对int的引用
    }否则{
    cout实例化错误
    }
    
    更好:

    template<typename T>
    void foo(T x) {
        cout << "haha\n";
    }
    void foo(int* x) {
        *x = 23;
    }
    int main() {
        foo(42); // fine, invokes foo<int>(int)
    }
    
    模板
    void foo(T x){
    
    我想你在什么地方把抽象概念弄错了

    <>我将尝试从需要公开的接口(在C++中用纯虚方法抽象抽象类)重新定义A、B&C。 模板基本上允许duck类型,但听起来CFoo对abc类了解得太多了

    typeid不正确,因为:

  • typeid可能会很贵,女士 二进制文件,携带额外的 不应该被删除的信息 必需的
  • 并非所有编译器都支持它
  • 它基本上打破了类的层次结构

  • 我建议的是重构:删除模板,而是为A、B和C定义接口,并让CFoo获取这些接口。这将迫使您重构行为,使A、B和C实际上是内聚类型。

    一般来说,在没有RTTI的情况下可以找到解决方案。它“可以”表明您没有正确地考虑软件的设计。这是不好的。但有时RTTI可能是一件好事

    尽管如此,您想做的事情还是有些奇怪。您能否创建一个临时模板,设计如下:

    template< class T > class TypeWrapper
    {
      T t;
    public:
      void DoSomething()
      {
      }
    };
    
    template<> class TypeWrapper< CSomeClass >
    {
      CSomeClass c;
    public:
      void DoSomething()
      {
         c.DoThatThing();
      }
    };
    
    templateclasstypewrapper
    {
    T;
    公众:
    无效剂量测定法()
    {
    }
    };
    
    然后,对您想要实现的功能进行部分专业化,如下所示:

    template< class T > class TypeWrapper
    {
      T t;
    public:
      void DoSomething()
      {
      }
    };
    
    template<> class TypeWrapper< CSomeClass >
    {
      CSomeClass c;
    public:
      void DoSomething()
      {
         c.DoThatThing();
      }
    };
    
    模板类TypeWrapper
    {
    c类;
    公众:
    无效剂量测定法()
    {
    c、 DoThatThing();
    }
    };
    
    然后在你的课堂上,你会做一些事情,比如

    模板

      class CFoo
      {
         TypeWrapper< A > a;
         TypeWrapper< B > b;
         TypeWrapper< C > c;
         void foo()
         {
           a.DoSomething();
           b.DoSomething();
           c.DoSomething();
         }
    
      }
    
    类CFoo
    {
    类型包装A;
    类型包装B;
    类型包装C;
    void foo()
    {
    a、 DoSomething();
    b、 DoSomething();
    c、 DoSomething();
    }
    }
    

    这样,它实际上只在通过部分专门化模板时在“DoSomething”调用中执行某些操作。

    问题在于为每个专门化编写的代码块

    你是否(纵向)写作并不重要


    第二种情况的好处是,当您添加一个类D时,编译器会提醒您必须编写一个foo_uuu缺失的重载。在第一种变体中,这可能会被忘记。

    我担心这首先是行不通的。那些“代码块”即使类型不是CSomeClass,也必须是可编译的

    我认为类型_也不会有帮助(如果它与C++0x中的auto和decltype相同)

    我认为您可以将这三个块提取到单独的函数中,并为CSomeClass重载每个块。(编辑:哦,有
    或者if的
    。那么您可能确实需要大量重载/专门化。这段代码用于什么?)

    Edit2:您的代码似乎希望执行以下等效操作,其中int是特殊类型:

    #include <iostream>
    
    template <class T>
    bool one() {return false; }
    
    template <>
    bool one<int>() { std::cout << "one\n"; return true; }
    
    template <class T>
    bool two() {return false; }
    
    template <>
    bool two<int>() { std::cout << "two\n"; return true; }
    
    template <class T>
    bool three() {return false; }
    
    template <>
    bool three<int>() { std::cout << "three\n"; return true; }
    
    template <class A, class B, class C>
    struct X
    {
        void foo()
        {
            one<A>() || two<B>() || three<C>();
        }
    };
    
    int main()
    {
        X<int, double, int>().foo(); //one
        X<double, int, int>().foo();  //two
        X<double, double, double>().foo(); //...
        X<double, double, int>().foo(); //three
    }
    
    #包括
    模板
    bool one(){return false;}
    模板
    bool one(){std::cout
    
    void foo()
    {
       A x;
       foo_( x );
       B y;
       foo_( y );
       C z;
       foo_( z );
    }
    void foo_( CSomeClass1& ) {}
    void foo_( CSomeClass2& ) {}
    void foo_( CSomeClass3& ) {}
    
    #include <iostream>
    
    template <class T>
    bool one() {return false; }
    
    template <>
    bool one<int>() { std::cout << "one\n"; return true; }
    
    template <class T>
    bool two() {return false; }
    
    template <>
    bool two<int>() { std::cout << "two\n"; return true; }
    
    template <class T>
    bool three() {return false; }
    
    template <>
    bool three<int>() { std::cout << "three\n"; return true; }
    
    template <class A, class B, class C>
    struct X
    {
        void foo()
        {
            one<A>() || two<B>() || three<C>();
        }
    };
    
    int main()
    {
        X<int, double, int>().foo(); //one
        X<double, int, int>().foo();  //two
        X<double, double, double>().foo(); //...
        X<double, double, int>().foo(); //three
    }