Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this correct behavior of template?

Tags:

c++

templates

template<class blah, class bleh>
blah func(bleh p)
{
    // Do something
}

int main()
{
    double d=1.111;
    int i = func<int>(d); // #1
    int j = func<int,double>(d); // #2
    // ....
}

In this example both the instances of func, #1 and #2 are compiling, but I'm unsure of what is correct, and why.

Can some one explain why #1 is correct, and maybe give some background?

like image 344
tejas Avatar asked Nov 03 '14 07:11

tejas


People also ask

What is a template argument?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

How do you call a function in a template?

A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.

What is a non type template parameter?

A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.

How are C++ templates compiled?

Template compilation requires the C++ compiler to do more than traditional UNIX compilers have done. The C++ compiler must generate object code for template instances on an as-needed basis. It might share template instances among separate compilations using a template repository.


1 Answers

Yes, this is correct behaviour.

Case 1 - type deduction

func<int>(d);

This uses template type deduction to determine the type for bleh.

In order to instantiate a function template, every template argument must be known, but not every template argument has to be specified. When possible, the compiler will deduce the missing template arguments from the function arguments. This occurs when a function call is attempted and when an address of a function template is taken.

The compiler sees the type for d as being a double and thus deduces the actual type for bleh must also be a double.

From cppreference, also covered in § 14.8.2 of the C++ specification;

Template argument deduction attempts to determine template arguments ..., which can be substituted into each parameter P to produce the type deduced A, which is the same as the type of the argument A, ... .

If there are multiple parameters, each P/A pair is deduced separately and the deduced template arguments are then combined. If deduction fails or is ambiguous for any P/A pair or if different pairs yield different deduced template arguments, or if any template argument remains neither deduced nor explicitly specified, compilation fails.

Case 2

func<int,double>(d);

The type for bleh is explicitly set to double, hence the compiler will make it such. The argument d is provided and since it is also a double, the compiler happily continues. If an argument (i.e. in place of d) was provided with a type that was not a double, or could not implicitly be converted to a double (e.g. via promotions, non-explicit constructors or user provided conversions), this would result in an error.

like image 68
Niall Avatar answered Sep 28 '22 06:09

Niall