简体   繁体   中英

C++11 constructor inheritance through variadic templates

I recently came across an instance in which I realized that several classes I had written shared a lot of functionality. I realized I could generalize these classes into a common base with some template parameters. The problem is that these classes have about 20 different overloaded constructors, where most of the classes functionality is implemented. Using I came up with the solution illustrated here:

template <typename T>
class Base {

  protected:

    T member_;

  public:

    Base(int a) { /* ... */ }

    Base(double a) { /* ... */ }

    Base(char a) { /* ... */ }

    Base(int a, double b, char c) { /* ... */ }

    // etc...

};

class Derived1 : public Base<int> {

  public:

    template <typename... Args>
    Derived1(Args... args) : Base(args...) { }

    // other constructors specific to Derived1

};

class Derived2 : public Base<char> {

  public:

    template <typename... Args>
    Derived2(Args... args) : Base(args...) { }

    // other constructors specific to Derived2

};

I have several questions here:

  1. Is there any runtime performance hit associated with this? (After looking around, it seems like I should be using rvalue references and std::forward in the derived classes, right?)
  2. From a code maintainability point of view, is this a good idea?
  3. What are some pitfalls of this approach? (eg similar examples elsewhere seem to be using the explicit keyword. Why?)
  4. Is there a better, more standard, more safe, or more readable way to do this?

In C++11 , constructors can be inherited.

See https://stackoverflow.com/a/434784/232574

  1. Yes, you should be using perfect forwarding. If the constructors are declared inline, there will be zero performance impact.

  2. It is a "scary-looking template," but easily recognized by someone who knows anything about templates. Depends on your maintainers, I guess?

  3. You need to beware of intercepting calls intended for the derived class's copy and move constructor, since your variadic perfect forwarding signature matches everything . Properly constraining with enable_if usually requires more code than the forwarding constructor itself.

  4. Inheriting constructors is the "better" way to do this. The feature is specified to avoid capturing signatures that should go to the derived class constructors. Compiler support may be iffy: it's not the easiest feature to implement, or the most in-demand, so implementors put it off for quite a while.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM