Home > database >  Why type deduction fails for a class member?
Why type deduction fails for a class member?

Time:11-16

Let's assume that we have this small code:

template<typename T>
struct Test {
    Test(T t) : m_t(t) {}
    T m_t;
};

int main() {
    Test t = 1;
}

This code easily compiles with [T=int] for Test class. Now if I write a code like this:

template<typename T>
struct Test {
    Test(T t) : m_t(t) {}
    T m_t;
};

struct S {
    Test t = 1;
};

int main() {
    S s;
}

This code fails to compile with the following error:

invalid use of template-name 'Test' without an argument list

I need to write it like Test<int> t = 1; as a class member to work. Any idea why this happens?

CodePudding user response:

The reason

struct S {
    Test t = 1;
};

does not work is because you aren't actually doing Test t = 1;. An in class initializer is just a convenient way to tell the compiler what value to initialize t with when one is not provided. What "actually" gets generated is

struct S {
    S() : t(1) {} // created by the compiler
    Test t;
};

and here you can more easily see that t isn't specified with an initializer until you call the constructor.

CodePudding user response:

There is a difference between your two snippets - first Test t = 1 declares, defines, and initializes a new variable while the second only declares a member variable and specifies how it might be initialized.

The default member initializer is relevant only in the context of a constructor without t in its member initializer list and there can easily be multiple constructors, each initializing t in different way.

The following is valid C , what should type of t be deduced to?

struct S {
    Test t = 1;
    S(){}
    S(int):t(1){}
    S(double):t(true){}
};

If this were to be supported, you hit the implementation issue of making type/size/layout of the class dependent on the definition of constructors which are likely in different translation units. Therefore it would make it impossible to define include classes such as S (if one moved the definitions to some .cpp) via header files.

  • Related