Let’s assume we want to print out the attribute of an arbitrary class through two different functions: One function takes a parameter const Widget&
, the other one is a function template that takes a parameter of type const T&
. We pass one argument of type Widget
and Widget&
respectively. The code can look like the following:
#include <iostream>
#include <vector>
class Widget {
public:
friend std::ostream &operator<<( std::ostream &output, const Widget &w ) {
output << "Attr : " << w.attr;
return output;
}
private:
int attr = 5;
};
void f(const Widget& param) {
std::cout << param << std::endl;
}
template<typename T>
void f2(const T& param) {
std::cout << param << std::endl;
}
int main() {
std::vector<Widget> arg = {Widget()};
if (!arg.empty()) {
f(arg[0]);
//f(&arg[0]); <-- This leads to a compile time error. Why?
f2(arg[0]);
f2(&arg[0]); // <-- In contrast, why does this work if the above fails?
}
}
Why can we pass an address as argument in the function template, but not in the function? What is T
in both valid cases?
Output:
Attr : 5
Attr : 5
0x55feee619eb0
Thanks in advance for the help!
>Solution :
A pointer is not a reference. A reference is not a pointer. arg[0]
evaluates to a reference to an object. &arg[0]
evaluates to a pointer to the object. That’s what the unary &
operator does: it produces a pointer to some object.
The function takes a reference to an object as its parameter, and not a pointer. That’s the reason for the compilation error.
As far as the template is concerned, the template parameter gets deduced to be a pointer to an object, and the instantiated template’s parameter is a reference to a pointer. The instantiated template’s parameter is a Widget * const &
, a reference to a const
pointer to a Widget
.