1

This:

template <typename T>
struct base {
    T a;
};

template <typename T>
struct derived : base<T> {
    derived(T v) : a(v) {} // xxx: how?
};

int main() {
    return 0;
}

Goes boom:

test.cc: In constructor ‘derived<T>::derived(T)’:
test.cc:12:20: error: class ‘derived<T>’ does not have any field named ‘a’
     derived(T v) : a(v) {} // xxx: how?

If I replace the a(v) with { this->a = v; } it's fine, is there any way to initialize members of a templated base class from the initializer list of a derived class?

3
  • 1
    You can't, and this has nothing to do with templates. A class can only initialize its own class's members. As far as the base classes go, the only thing it can do is invoke the base class's constructor, and it is the base class's constructor that's responsible for initializing its own members. Commented Oct 3, 2018 at 16:38
  • 2
    Yes, call a base class constructor that initializes them. Commented Oct 3, 2018 at 16:38
  • @SamVarshavchik Ah I didn't know that, surprised I haven't run into it before. I'm doing some weird mix-in stuff at the moment so that's why. I'll stick with using this->a = v; Commented Oct 3, 2018 at 16:39

2 Answers 2

5

You need to initialize the base class in the member initialization list of the derived class. Since your base doesn't have a constructor you can use curly brace initialization (uniform initialization) like

template <typename T>
struct base {
    T a;
};

template <typename T>
struct derived : base<T> {
    derived(T v) : base<T>{v} {}
};
Sign up to request clarification or add additional context in comments.

1 Comment

You edited out the comment right as I did. That was pretty quick :)
2

Create a constructor in the base class and call it in the initialization list of the derived class. ie:

template <typename T>
struct base {
    T a;
    base(T v) : a(v) { }
};

template <typename T>
struct derived : base<T> {
    derived(T v) : base(v) {}
};

2 Comments

That's the consensus, unfortunately my number of constructor arguments depends on a template parameter (dimensionality for a vector class), so I was inheriting to provide proper constructors, I'll just use the this-> syntax
@SeanMcAllister you can always overload the base constructor for different cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.