简体   繁体   中英

Need help regarding Template class instantiation

Let me present my problem with an example:

template <typename T> class a{
public:
    T data;
    a():data(T()){}
    a(T temp): data(temp) {}
};

So if write in main() like

a(30);
a("String");

So according to the template argument deduction rule, it should be able to generate the first temporary class as a<int>(30) etc

But I the error which says:

missing template arguments before '(' token

so why this happens, this is only true for function template?

Template parameter deduction from arguments only works for functions , never for classes . Until you know the type of the class, ie all its template parameters, you don't even know which member functions the class has!

So, you always have to say the template parameters if you want to construct an object directly:

a<int> x(30);

Here's a little thought experiment to expand on the above. Suppose we have

template <typename T> class Foo;

and we are calling Foo::somefunction(x); , where x is some type. You think, well, I declared somefunction() like this:

template <typename T> class Foo
{
  static void somefunction(const T & x);
};

so it should be obvious that T is the same type as the type of x . But now imagine I have a specialization:

template <> class Foo<char>
{
  static void anotherfunction(double x);
};

The class Foo<char> doesn't even have a function somefunction() , so the expression Foo::somefunction(x) doesn't even get to the stage where I could look up the argument!

The usual way around this is to make a free helper function that constructs your object:

template <typename T> a<T> make_a(const T & x) { return a<T>(x); }

Since this is a function template, its parameters can be deduced:

make_a(30);      // type a<int>
make_a("hello"); // type a<char[6]>

The constructor is not a template, its the class which is a template. So when you write a(30) , the template argument deduction for the class template cannot be done!

If there exists a constructor template, then the template argument for the templated constructor can be deduced by the compiler. For example here:

template <typename T> class A{
public:
    template<typename U>
    A(const U &): {}   //note : it's a constructor template
};

A<char>  obj(30); //U is deduced as int

In the above example, only U can be deduced, you still have to provide T . Its because

  • U is a template argument for the constructor template. Template argument deduction can be done in this case.
  • T is a template argument for the class template. Template argument deduction cannot be done here.

You still need to declare a temporary as, for example, a<int>(30) .

You cannot infer class template arguments from the arguments to the constructor- unfortunately.

Template type deduction only happens for template functions. You need to specify the parameters for a template class instantiation. You can use a function template to deduce the template parameter and return the appropriate type. In c++0 x you could use auto to hold the instance. Can't easily write example code for you on my phone!

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