How do I call a friend template function defined inside a class? - c++

I got this example from my book, but I have no idea how to actually call the ticket function. This is the code:
#include <iostream>
class Manager {
public:
template<typename T>
friend int ticket() {
return ++Manager::counter;
}
static int counter;
};
int main()
{
Manager m;
std::cout << "ticket: " << ticket<int>() << std::endl;
}
I get the "candidate function(s) not accessible" error message.

A few points will help you figure out what's going on here:
I) Friend function definitions within classes can only be found by Argument dependent lookup when called from outside the class definition.
II) Function templates that are supplied explicit template arguments do not undergo ADL unless the compiler is given some explicit help in identifying the call as a function call.
III) Argument dependent lookup (ADL) only works for user defined types.
A few examples will better illustrate each of the above points:
//------------------------
struct S
{
friend int f(int) { return 0; } // 1
friend int f(S) { return 0; } // 2
};
S s;
int i = f(3); // error - ADL does not work for ints, (III)
int j = f(s); // ok - ADL works for UDTs and helps find friend function - calls 2 (III)
// so how do we call function 1? If the compiler won't find the name via ADL
// declare the function in the namespace scope (since that is where the friend function
// gets injected)
int f(int); // This function declaration refers to the same function as #1
int k = f(3); // ok - but not because of ADL
// ok now lets add some friend templates and make this interesting
struct S
{
friend int f(int) { return 0; } // 1
friend int f(S) { return 0; } // 2
template<class T> friend int g(int) { return 0; } // 3
template<class T> friend int g(S) { return 0; } // 4
template<class T> friend int g() { return 0; } // 5
};
S s;
int k = g(5); // error - no ADL (III)
int l = g(s); // ok - ADL - calls 4
int m = g<int>(s); // should call 4 - but no ADL (point II above)
// ok so point II above says we have to give the compiler some help here
// We have to tell the compiler that g<int> identifies a function
// The way to do that is to add a visible dummy template function declaration
template<class /*Dummy*/, class /*TriggerADL*/> void g();
int m = g<int>(s); // ok - compiler recognizes fun call, ADL triggered - calls 4
int n = g<int>(3); // still not ok - no ADL for ints
// so how do we call either function 3 or 5 since we cannot rely on ADL?
// Remember friend functions are injected into the outer namespace
// so lets just declare the functions in the outer namespace (as we did above)
// both these declarations of g below refer to their counterparts defined in S
template<class T> int g(int);
template<class T> int g();
int o = g<int>(3); // ok
int p = g<int>(); // ok
// Of course once you have these two declarations at namespace scope
// you can get rid of the Dummy, TriggerADL declaration.
Ok so now lets return to the Vandevoorde example that you quoted, and now this should be easy:
#include <iostream>
class Manager {
public:
template<typename T>
friend int ticket() {
return ++Manager::counter;
}
static int counter;
};
int Manager::counter;
template<class T> int ticket(); // <-- this should work with a conformant compiler
int main()
{
Manager m;
std::cout << "ticket: " << ticket<int>() << std::endl;
}
Hope that helps :)

Hotfix
There is a hot-fix available, but read the below explanation if you want to understand what's going on.
#include <iostream>
template<typename T> int ticket();
class Manager {
public:
template<typename T>
friend int ticket() {
return ++Manager::counter;
}
static int counter;
};
int Manager::counter; // don't forget the definition
int main() {
Manager m;
std::cout << "ticket: " << ticket<int>() << std::endl;
}
As the snippet shows, you have to declare the template to make it visible when you call it.
Friend function definitions
This is confusing, since there are some rules in the way in this case. Some basic points, and then some other points.
struct A {
friend void f(A*) { std::cout << "hello"; }
};
What does it do? It defines a friend function. Such a function is a member of the enclosing namespace. It's not a class member, even though it is defined within a class! The fact that it's defined within a class only changes the lexical scope of that function: It can refer to that class' members directly, without preceding the class-name.
Most importantly, though, the function is not visible after being declared. You cannot take its address doing something like this, for example
&f
The only way that the function would work is using argument dependent lookup. A lookup that ends up having that class as its associated class will consider that friend function. That means that the following works:
f((A*)0);
It works because the call includes an argument with type that has the class included. In that case, the class is an associated class, and the friend declaration will be considered.
The following won't work, for example
f(0);
Because it has no idea that it should look within A to find a friend declaration. A friend function definition of a function without an argument won't be found, because there is no argument dependent lookup happening, then.
Friend function definition for templates
In addition to the fact that your call does not include arguments, it has another problem. If you define a friend function template, the matter is more complicated. There is a rule that says that if the compiler sees T<A1, A2, A3>, that this only refers to a template specialization if T actually resolves to a template. Consider
ticket < int > ()
The compiler can't resolve ticket, because it is not visible to normal lookup. Therefor, the rule says that ticket<int> does not refer to a function. It has to be parsed as a relational expression, yielding to the following
(ticket < int) > ()
That will be a syntax error, because int is not a value, and () is neither a value.
Example
Here is an example where it matters.
struct A {
template<int I> friend void f(A*) { }
};
// try to comment this out
template<typename Dummy> void f();
int main() {
f<1>((A*)0);
}
That compiles. It compiles because f resolves to a template (although a completely different one that can't even accept a non-type template argument - but that doesn't matter!). But a Standard conforming compiler will not compile the snippet once you comment out the second declaration, because it's compiled as a relational expression (less-than and smaller-than) and it will not find symbol f.
Read this thread for further information: What am I missing in this template toy example?.

I do get the same error using the MS VS++ compiler. According to the docs on MSDN:
http://msdn.microsoft.com/en-us/library/h2x4fzdz(VS.80).aspx
Friends are not in the class's scope,
and they are not called using the
member-selection operators (. and –>)
unless they are members of another
class. A friend function is declared
by the class that is granting access.
So friend functions are not actually part of the class and should therefore not be defined in class scope. Define the function outside of the class:
#include <iostream>
class Manager {
public:
template<typename T>
friend int ticket();
static int counter;
};
template<typename T>
int ticket() {
return ++Manager::counter;
}
int Manager::counter;
int main()
{
Manager m;
std::cout << "ticket: " << ticket<int>() << std::endl;
}

Why not make it static instead?
#include <iostream>
class Manager {
public:
template<typename T>
static int ticket()
{
return ++Manager::counter;
}
static int counter;
};
int main()
{
Manager m;
std::cout << "ticket: " << Manager::ticket<int>() << std::endl;
}
Though really, it doesn't have to be a template either. I assume you needed information specifically about friend templates?

Related

Template explicit specialization in class using inheritance

Yesterday I asked about template explicit specialization in class.
Link.
Now I have the same purpose but now I wanna use inheritance to avoid code duplication. If I declare a function in the base class I cannot declare specialization of this function in the derived class.
My code:
#include <stdexcept>
#include <iostream>
class Base
{
public:
template <typename T>
T fun()
{
throw std::runtime_error("Unsupported template param");
}
};
class Derived : public Base
{
};
template <>
bool Base::fun<bool>()
{
return true;
}
template <>
float Derived::fun<float>()
{
return 5.6f;
}
template <>
double Derived::fun<double>()
{
return 5.684;
}
int main()
{
Derived d;
bool d_b = d.fun<bool>();
float d_f = d.fun<float>();
double d_d = d.fun<double>();
char d_error = d.fun<char>();
}
VS code errors:
use of inherited members is not allowed
g++
error: template id "fun" for "float Derived :: fun ()" does not match any template declaration
Intel C++ compiler:
source/app.cpp:25:16: error: no function template matches function template specialization 'fun'
float Derived::fun<float>()
^
source/app.cpp:30:1: error: extraneous 'template<>' in declaration of variable 'fun'
template <>
^~~~~~~~~~~
source/app.cpp:31:17: error: redefinition of 'fun' as different kind of symbol
double Derived::fun<double>()
^
source/app.cpp:25:16: note: previous definition is here
float Derived::fun<float>()
If it is impossible in C++, please answer another question: what is a wide-known practice in c++ to do what I want. Before I used D language and one man says me I don't ask a question "Why" to myself. And instead, I just try to transfer D methods to C++. I agree. That's why I ask.
Maybe a better way is to ignore templates and declare separated functions? For example:
funToBool()
funToFloat()
funToDouble()
This will compile if you add a public template definition of fun in Derived.
But that will probably not do what you want.
In particular d.fun<bool>(); will not execute the implementation in Base, but the implementation in Derived.
You cannot specialize template functions in derived classes.
You also cannot use subtype polymorphism on template functions: template cannot be virtual.
You can achieve some type of static polymorphism using CRTP.
Yes removing templates and working with separated functions would work (a.toX()...).
Another option is to work with overloads (i.e. passing a dummy argument or the destination variable and write different implementations).
Adding an example for the dummy argument solution as requested:
namespace TO {
static const bool BOOL = false;
static const double DOUBLE = 0.0;
static const int INT = 0;
}
struct A {
bool convert(bool dummy) {
return true;
}
};
struct B : public A {
using A::convert; // important
int convert(int dummy) {
return 2;
}
double convert(double dummy) {
return 3.0;
}
};
int main() {
B b;
std::cout << b.convert(TO::BOOL) << std::endl;
std::cout << b.convert(TO::DOUBLE) << std::endl;
std::cout << b.convert(TO::INT) << std::endl;
}
With this kind of solution there is a risk of implicit conversion when calling the function. toX() might be a safer option.

Why ADL has a different behavior for operator function than other functions?

I have created a C class inside a NS_C namespace that way:
#include <iostream>
namespace NS_C {
template <typename T>
class C {
public:
C operator+(long) {
std::cout << "NS_C::C::operator+\n";
return *this;
}
void not_operator(C<T>, long) {
std::cout << "NS_C::C::not_operator\n";
}
void call() {
*this + 0;
not_operator(*this, 0);
}
};
}
The function call is supposed to call NS_C::C::operator+ then NS_C::C::not_operator. To test this behavior, I run this small program:
int main()
{
NS_C::C<int> ci;
ci.call();
return 0;
}
The output is what I expected:
> g++ -o example example.cpp && ./example
NS_C::C::operator+
NS_C::C::not_operator
Now, I want to create a new class A within a separate namespace NS_A and add to this namespace two generic overloads of operator+ and not_operator functions:
#include <iostream>
namespace NS_A {
class A {};
template <typename T>
T operator+(T t, int)
{
std::cout << "NS_A::operator+\n";
return t;
}
template <typename T>
void not_operator(T, int)
{
std::cout << "NS_A::not_operator\n";
}
}
Thanks to ADL, a call to call member function from an NS_C::C<NS_A> object will call the overloaded NS_A::operator+ as it is better match (the second parameter is int in NS_A::operator+ and long in NS_C::C::operator+).
However, I don't understand why the same behavior doesn't occur for my not_operator function. Indeed, NS_C::C::not_operator will still be called from call function.
Let's use the following main function:
int main()
{
NS_C::C<NS_A::A> ca;
ca.call();
return 0;
}
I have the following output:
NS_A::operator+
NS_C::C::not_operator
Why NS_A::not_operator is not called in that case?
Here is the complete code to reproduce the issue:
#include <iostream>
namespace NS_A {
class A {};
template <typename T>
T operator+(T t, int)
{
std::cout << "NS_A::operator+\n";
return t;
}
template <typename T>
void not_operator(T, int)
{
std::cout << "NS_A::not_operator\n";
}
}
namespace NS_C {
template <typename T>
class C {
public:
C operator+(long) {
std::cout << "NS_C::C::operator+\n";
return *this;
}
void not_operator(C<T>, long) {
std::cout << "NS_C::C::not_operator\n";
}
void call() {
*this + 0;
not_operator(*this, 0);
}
};
}
int main()
{
NS_C::C<int> ci;
ci.call();
NS_C::C<NS_A::A> ca;
ca.call();
return 0;
}
From overload_resolution#Call_to_an_overloaded_operator:
We have in overload sets of candidates for overloaded operator:
1) member candidates: if T1 is a complete class or a class currently being defined, the set of member candidates is the result of qualified name lookup of T1::operator#. In all other cases, the set of member candidates is empty.
2) non-member candidates: For the operators where operator overloading permits non-member forms, all declarations found by unqualified name lookup of operator# in the context of the expression (which may involve ADL), except that member function declarations are ignored and do not prevent the lookup from continuing into the next enclosing scope. If both operands of a binary operator or the only operand of a unary operator has enumeration type, the only functions from the lookup set that become non-member candidates are the ones whose parameter has that enumeration type (or reference to that enumeration type)
Whereas for the other, we only have unqualified_lookup
There is even an example in unqualified_lookup#Overloaded_operator
showing difference between operator+(a, a) and a + a

Template inheritance: There are no arguments that depend on a template parameter [duplicate]

This question already has an answer here:
g++ template parameter error
(1 answer)
Closed 6 years ago.
I came across this error when compiling the following code.
After doing some research and reading similar errors in different situations, I came up with the solution I needed.
But I did not fully understood the undelying reason for the error and the fix.
template <typename T>
class TestA {
int a;
T temp;
protected:
int b;
public:
int c;
TestA(T te): a{10}, b{20}, c{30}, temp{te} {}
int geta(){ return a; }
int getb(){ return b; }
int getc(){ return c; }
};
template <typename T>
class TestB {
int atb;
T tempb;
protected:
int btb;
public:
int ctb;
TestB(T te) atb{10}, btb{20}, ctb{30}, tempb{te} {}
};
template <typename T>
class TestInh : public TestA<T>, public TestB<T> {
int aa;
T temptemp;
protected:
int bb;
int b;
public:
int cc;
TestInh(T te) : TestA<T>{te}, TestB<T>{te}, bb{10000}, b{-1000} {}
int get_total() {
// The error happens here!
return geta();
}
};
int main(int argc, char const *argv[]) {
char text = 'a';
TestInh<char> test(text);
//std::cout << test.geta() << std::endl;
std::cout << test.get_total() << std::endl;
//std::cout << test.c << std::endl;
return 0;
}
When compiling this code, I got this error:
testtemplate.cc: In member function ‘int TestInh<T>::get_total()’:
testtemplate.cc:54:32: error: there are no arguments to ‘geta’ that depend on a template parameter, so a declaration of ‘geta’ must be available [-fpermissive]
int get_total() {return geta();}
^
testtemplate.cc:54:32: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
It is solved by calling this->geta() instead of just geta(), but I do not fully understand why this cannot be resolved by the compiler.
Can someone please explain me why?
When extending a class that depends on a template parameter, this kind of become a dependent name.
The problem is that while performing two phase name lookup, the compiler can't know where he can find the function geta. He cannot know it comes from the parent. Because template specialization is a thing, TestA<int> and TestA<double> could be two completely different clas swith different functions and members.
With the this keyword added, the compiler know that geta must be a member function.
Without that, it could be either a member function or non-member function, or a member function of TestB.
Imagine a template code that will either call a function geta from TestA and geta from TestB depending on some template conditions. Ouch. The compiler want to be sure that the code is consistent for every template instantiations.
Another way of saying to the compiler that the function exist as a member function is to add a using statement:
template <typename T>
struct TestInh : TestA<T>, TestB<T> {
// some code...
using TestA<T>::geta;
int get_total() {
// works! With the above using statement,
// the compiler knows that 'geta()' is
// a member function of TestA<T>!
return geta();
}
};

advantages of this pointer [duplicate]

When should I explicitly write this->member in a method of
a class?
Usually, you do not have to, this-> is implied.
Sometimes, there is a name ambiguity, where it can be used to disambiguate class members and local variables. However, here is a completely different case where this-> is explicitly required.
Consider the following code:
template<class T>
struct A {
T i;
};
template<class T>
struct B : A<T> {
T foo() {
return this->i; //standard accepted by all compilers
//return i; //clang and gcc will fail
//clang 13.1.6: use of undeclared identifier 'i'
//gcc 11.3.0: 'i' was not declared in this scope
//Microsoft C++ Compiler 2019 will accept it
}
};
int main() {
B<int> b;
b.foo();
}
If you omit this->, some compilers do not know how to treat i. In order to tell it that i is indeed a member of A<T>, for any T, the this-> prefix is required.
Note: it is possible to still omit this-> prefix by using:
template<class T>
struct B : A<T> {
int foo() {
return A<T>::i; // explicitly refer to a variable in the base class
//where 'i' is now known to exist
}
};
If you declare a local variable in a method with the same name as an existing member, you will have to use this->var to access the class member instead of the local variable.
#include <iostream>
using namespace std;
class A
{
public:
int a;
void f() {
a = 4;
int a = 5;
cout << a << endl;
cout << this->a << endl;
}
};
int main()
{
A a;
a.f();
}
prints:
5
4
There are several reasons why you might need to use this pointer explicitly.
When you want to pass a reference to your object to some function.
When there is a locally declared object with the same name as the member object.
When you're trying to access members of dependent base classes.
Some people prefer the notation to visually disambiguate member accesses in their code.
Although I usually don't particular like it, I've seen others use this-> simply to get help from intellisense!
There are few cases where using this must be used, and there are others where using the this pointer is one way to solve a problem.
1) Alternatives Available: To resolve ambiguity between local variables and class members, as illustrated by #ASk.
2) No Alternative: To return a pointer or reference to this from a member function. This is frequently done (and should be done) when overloading operator+, operator-, operator=, etc:
class Foo
{
Foo& operator=(const Foo& rhs)
{
return * this;
}
};
Doing this permits an idiom known as "method chaining", where you perform several operations on an object in one line of code. Such as:
Student st;
st.SetAge (21).SetGender (male).SetClass ("C++ 101");
Some consider this consise, others consider it an abomination. Count me in the latter group.
3) No Alternative: To resolve names in dependant types. This comes up when using templates, as in this example:
#include <iostream>
template <typename Val>
class ValHolder
{
private:
Val mVal;
public:
ValHolder (const Val& val)
:
mVal (val)
{
}
Val& GetVal() { return mVal; }
};
template <typename Val>
class ValProcessor
:
public ValHolder <Val>
{
public:
ValProcessor (const Val& val)
:
ValHolder <Val> (val)
{
}
Val ComputeValue()
{
// int ret = 2 * GetVal(); // ERROR: No member 'GetVal'
int ret = 4 * this->GetVal(); // OK -- this tells compiler to examine dependant type (ValHolder)
return ret;
}
};
int main()
{
ValProcessor <int> proc (42);
const int val = proc.ComputeValue();
std::cout << val << "\n";
}
4) Alternatives Available: As a part of coding style, to document which variables are member variables as opposed to local variables. I prefer a different naming scheme where member varibales can never have the same name as locals. Currently I'm using mName for members and name for locals.
Where a member variable would be hidden by
a local variable
If you just want
to make it explictly clear that you
are calling an instance method/variable
Some coding standards use approach (2) as they claim it makes the code easier to read.
Example:
Assume MyClass has a member variable called 'count'
void MyClass::DoSomeStuff(void)
{
int count = 0;
.....
count++;
this->count = count;
}
One other case is when invoking operators. E.g. instead of
bool Type::operator!=(const Type& rhs)
{
return !operator==(rhs);
}
you can say
bool Type::operator!=(const Type& rhs)
{
return !(*this == rhs);
}
Which might be more readable. Another example is the copy-and-swap:
Type& Type::operator=(const Type& rhs)
{
Type temp(rhs);
temp.swap(*this);
}
I don't know why it's not written swap(temp) but this seems to be common.
The other uses for this (as I thought when I read the summary and half the question... .), disregarding (bad) naming disambiguation in other answers, are if you want to cast the current object, bind it in a function object or use it with a pointer-to-member.
Casts
void Foo::bar() {
misc_nonconst_stuff();
const Foo* const_this = this;
const_this->bar(); // calls const version
dynamic_cast<Bar*>(this)->bar(); // calls specific virtual function in case of multi-inheritance
}
void Foo::bar() const {}
Binding
void Foo::baz() {
for_each(m_stuff.begin(), m_stuff.end(), bind(&Foo:framboozle, this, _1));
for_each(m_stuff.begin(), m_stuff.end(), [this](StuffUnit& s) { framboozle(s); });
}
void Foo::framboozle(StuffUnit& su) {}
std::vector<StuffUnit> m_stuff;
ptr-to-member
void Foo::boz() {
bez(&Foo::bar);
bez(&Foo::baz);
}
void Foo::bez(void (Foo::*func_ptr)()) {
for (int i=0; i<3; ++i) {
(this->*func_ptr)();
}
}
Hope it helps to show other uses of this than just this->member.
You only have to use this-> if you have a symbol with the same name in two potential namespaces. Take for example:
class A {
public:
void setMyVar(int);
void doStuff();
private:
int myVar;
}
void A::setMyVar(int myVar)
{
this->myVar = myVar; // <- Interesting point in the code
}
void A::doStuff()
{
int myVar = ::calculateSomething();
this->myVar = myVar; // <- Interesting point in the code
}
At the interesting points in the code, referring to myVar will refer to the local (parameter or variable) myVar. In order to access the class member also called myVar, you need to explicitly use "this->".
You need to use this to disambiguate between a parameters/local variables and member variables.
class Foo
{
protected:
int myX;
public:
Foo(int myX)
{
this->myX = myX;
}
};
The main (or I can say, the only) purpose of this pointer is that it points to the object used to invoke a member function.
Base on this purpose, we can have some cases that only using this pointer can solve the problem.
For example, we have to return the invoking object in a member function with argument is an same class object:
class human {
...
human & human::compare(human & h){
if (condition)
return h; // argument object
else
return *this; // invoking object
}
};
I found another interesting case of explicit usage of the "this" pointer in the Effective C++ book.
For example, say you have a const function like
unsigned String::length() const
You don't want to calculate String's length for each call, hence you want to cache it doing something like
unsigned String::length() const
{
if(!lengthInitialized)
{
length = strlen(data);
lengthInitialized = 1;
}
}
But this won't compile - you are changing the object in a const function.
The trick to solve this requires casting this to a non-const this:
String* const nonConstThis = (String* const) this;
Then, you'll be able to do in above
nonConstThis->lengthInitialized = 1;

C++ adding friend to a template class in order to typecast

I'm currently reading "Effective C++" and there is a chapter that contains code similiar to this:
template <typename T>
class Num {
public:
Num(int n) { ... }
};
template <typename T>
Num<T> operator*(const Num<T>& lhs, const Num<T>& rhs) { ... }
Num<int> n = 5 * Num<int>(10);
The book says that this won't work (and indeed it doesn't) because you can't expect the compiler to use implicit typecasting to specialize a template.
As a soluting it is suggested to use the "friend" syntax to define the function inside the class.
//It works
template <typename T>
class Num {
public:
Num(int n) { ... }
friend
Num operator*(const Num& lhs, const Num& rhs) { ... }
};
Num<int> n = 5 * Num<int>(10);
And the book suggests to use this friend-declaration thing whenever I need implicit conversion to a template class type. And it all seems to make sense.
But why can't I get the same example working with a common function, not an operator?
template <typename T>
class Num {
public:
Num(int n) { ... }
friend
void doFoo(const Num& lhs) { ... }
};
doFoo(5);
This time the compiler complaints that he can't find any 'doFoo' at all.
And if i declare the doFoo outside the class, i get the reasonable mismatched types error. Seems like the "friend ..." part is just being ignored.
So is there a problem with my understanding? What is the difference between a function and an operator in this case?
The reason is that here
doFoo(5);
the compiler has no way of finding foo, given an int parameter. This would be the equivalent of calling your friend operator like this:
Num<int> n = 5 * 10;
This will "work", but not by calling the friend operator* defined in your Num class, but by calling the built-in operator* for integers, and then using the implicit conversion from Num's converting constructor.
The core problem is lookup. A friend declaration provides a declaration of a namespace level function, but the declaration is only available inside the class that is befriending it. In the example the book provides that is not an issue: the function takes two arguments of the enclosing type, as long as one of them is of the enclosing type, Argument Dependent Lookup will look inside the definition of the class and find the operator. In your case that is not the case, since there is a single argument and that needs a conversion, the compiler will not look inside the definition of the class.
Note that this is regardless of templates and conversions:
class A {
friend void f( int ) {}
friend void g( int, A ) {}
};
int main() {
f(5); // Error: lookup cannot find 'f' declared *only* inside A
g(5,A()); // Ok, one argument is 'A', lookup will find the function
}
In the case above, where there are no templates involved, you could potentially add a declaration at namespace level to fix it, but that is not really an option for template classes.
class A {
friend void f() { std::cout << "inside A\n"; }
};
void f(int); // only declaration
int main() {
f(5); // "inside A"
}
This cannot be done for a template (and for all instantiating types) as the friend declaration is a declaration of a non-templated function. Although you could can play with the code just for the sake of testing:
template <typename T>
struct Num {
Num(int x) ...
friend void f( Num const & );
};
Num<int> f(Num<int> const &); // only declaration
int main() {
f(5);
}
Yes these code compiler do not know how to work with it .
like
doFoo(5)
compiler do not know 5 is int