Initializing template base-class member types in derived-class initializer lists

前端 未结 3 826
暗喜
暗喜 2020-12-25 15:18

Here is some code outlining a problem I\'ve been wrestling with. The final problem (as far as g++ is concerned at the moment) is that: \"error: \'Foo-T\' was not declared in

3条回答
  •  轮回少年
    2020-12-25 15:53

    Sorry to be unhelpful, but I also do not see a way around this without doing exactly what you stated:

    As of now I can't see a way past using both the template argument and a matching derived-class constructor argument to accomplish this task.

    You will likely have to specialize a bit:

    template<>
    Bar::Bar (const foo_arg_t bar_arg, const a_arg_t a_arg)
    : Foo(bar_arg)   // base-class initializer
    {
        // the initialization of Foo_T has to be done outside the initializer list because it's not in scsope until here
        Foo_T = TypeA(a_arg);   // if an a_arg_t is passed in, then we set the Foo_T to TypeA, etc.
    }
    
    template< class T>
    Bar::Bar (const foo_arg_t bar_arg, const a_arg_t a_arg)
    : Foo(bar_arg)   // base-class initializer
    {
        // Throw exception?
    }
    
    template<>
    Bar::Bar (const foo_arg_t bar_arg, const b_arg_t b_arg)
    : Foo(bar_arg)
    {
        Foo_T = TypeB(b_arg);
    }
    
    template< class T >
    Bar::Bar (const foo_arg_t bar_arg, const b_arg_t b_arg)
    : Foo(bar_arg)
    {
        // Throw exception ?
    }
    

    Unfortunately, I do not have access to a compiler at the moment to check this code so be wary.


    In answer to your question/comment. I got the following to compile:

    #include 
    typedef int a_arg_t;
    typedef double b_arg_t;
    typedef std::string foo_arg_t;
    
    class TypeA {
    public:
      TypeA () {}
      TypeA (a_arg_t a) {}
    };
    
    class TypeB {
    public:
      TypeB () {}
      TypeB (b_arg_t b) {}
    };
    
    template 
    class Foo {
    public:
      Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg) {}
      T Foo_T;        // either a TypeA or a TypeB - TBD
      foo_arg_t _foo_arg;
    };
    
    // the derived class that should set the basse-member type (T Foo_T)
    template 
    class Bar : public Foo {
    public:
      Bar (const foo_arg_t bar_arg, const a_arg_t a_arg)
      : Foo(bar_arg)   // base-class initializer
      {
        Foo::Foo_T = TypeA(a_arg);
      }
    
      Bar (const foo_arg_t bar_arg, const b_arg_t b_arg)
      : Foo(bar_arg)
      {
        Foo::Foo_T = TypeB(b_arg);
      }
    };
    
    int main () {
      b_arg_t b_arg;
      a_arg_t a_arg;
      foo_arg_t bar_arg;
    
      Bar a (bar_arg, a_arg);  // try creating the derived class using TypeA
      Bar b (bar_arg, b_arg); // and another type for show
    
      return 0;
    }
    

提交回复
热议问题