Unusual initialization required to construct object in a templated class

Viewed 33

I have some code that is structured like so:

enum class Type {a,b, c, d};


template<typename T>
class External {
    public:
        External(Type t) {

        }
};


template<typename T>
class Base {};

template<typename T>
class Derived : Base<T> {
    public:
    private:
        External<int> e(Type::a);
};


int main() {
    Derived<int> der;

    return 0;
}

When compiled with g++, this gives the following error:

<source>:49:25: error: 'Type::a' is not a type
   49 |         External<int> e(Type::a);
      |                         ^~~~

Through some experimentation I found out that it works if I construct the object of type External differently:

template<typename T>
class Derived : Base<T> {
    public:
    private:
        External<int> e = External<int>(Type::a);
};

Why is that the case? Why does the compiler expect a type in the first case?

1 Answers

The compiler is trying to interpret e as member function, so it's trying to treat Type::a as a type.

For default member initializer, you can only use braced-init-list or equal-sign initializer (as you showed).

Through a default member initializer, which is a brace or equals initializer included in the member declaration and is used if the member is omitted from the member initializer list of a constructor.

template<typename T>
class Derived : Base<T> {
    public:
    private:
        External<int> e{Type::a};
};
Related