Is there any reason to use this-> - c++

I am programming in C++ for many years, still I have doubt about one thing. In many places in other people code I see something like:
void Classx::memberfunction()
{
this->doSomething();
}
If I need to import/use that code, I simply remove the this-> part, and I have never seen anything broken or having some side-effects.
void Classx::memberfunction()
{
doSomething();
}
So, do you know of any reason to use such construct?
EDIT: Please note that I'm talking about member functions here, not variables. I understand it can be used when you want to make a distinction between a member variable and function parameter.
EDIT: apparent duplicate:
Are there any reasons not to use "this" ("Self", "Me", ...)?

The only place where it really makes a difference is in templates in derived classes:
template<typename T>
class A {
protected:
T x;
};
template<typename T>
class B : A<T> {
public:
T get() {
return this->x;
}
};
Due to details in the name lookup in C++ compilers, it has to be made explicitly clear that x is a (inherited) member of the class, most easily done with this->x. But this is a rather esoteric case, if you don't have templated class hierarchies you don't really need to explicitly use this to access members of a class.

If there is another variable in the same scope with the same name, the this-> will remove the ambiguity.
void Bar::setFoo(int foo)
{
this->foo = foo;
}
Also it makes it clear that you're refering to a member variable / function.

To guarantee you trigger compiler errors if there is a macro that might be defined with the same name as your member function and you're not certain if it has been reliably undefined.
No kidding, I'm pretty sure I've had to do exactly this for that reason!

As "code reason", to distinguish a local parameter or value (that takes precedence) from a member:
class Foo
{
int member;
void SetMember(int member)
{
this->member = member;
}
}
However, that's bad practive to begin with, and usually can be solved locally.
The second reason is more "environment": it sometimes helps Intellisense to filter what I am really looking for. However, I also thing when I use this to find the member I am looking for I should also remove this.
So yes, there are good reasons, but they are all temporary (and bad on the long run).

I can think of readability like when you use additional parenthesis to make things clear.

I think it is mainly as an aid to the reader. It makes it explicit that what is being called is a method on the object, and not an ordinary function. When reading code, it can be helpful to know that the called function can change fields in the current object, for instance.

It's your own choice. I find it more clear when you use this. But if you don't like it, you can ommit it.

This is done to be explicit about the fact that the variable being used is a member variable as opposed to a local or global variable. It's not necessary in most cases, but being explicit about the scope could be helpful if you've trumped the variable with a declaration of the same name in a tighter scope.
At companies I've worked at, we just prepended "m_" to member variables. It can be helpful sometimes, and I much prefer it to using "this->".
Edit:
Adding a link to the GCC docs, which explain a case where using this-> is necessary to get a non-dependent lookup to work correctly.

This is really a matter of style and applies to many other languages such as Java and C#. Some people prefer to see the explicit this (or self, or Me, or whatever) and others do not. Just go with whatever is in your style guidelines, and if it's your project, you get to decide the guidelines.

There are many good answers, but none of them mention that using this-> in source code makes it easier to read, especially when you are reading a code of some long function, but even a short function, imagine a code:
bool Class::Foo()
{
return SomeValue;
}
from looking on this code, you can't clearly know what SomeValue is. It could be even some #define, or static variable, but if you write
bool Class::Foo()
{
return this->SomeValue;
}
you clearly know that SomeValue is a non-static member variable of the same class.
So it doesn't just help you to ensure that name of your functions or variables wouldn't conflict with some other names, but it also makes it easier for others to read and understand the source code, writing a self documenting source code is sometimes very important as well.

Another case, that has arrived on the scenes after C++11 is in lambdas where this is captured.
You may have something like:
class Example
{
int x;
public:
std::function<void()> getIncrementor()
{
return [this] () -> void
{
++(this->x);
}
}
};
Although your lambda is generated within a class, it will only have access to local variables by capturing them (if your compiler does C++14) or capturing this. In the second case, inside the body of lambda, there simply is not x, but only this->x.

I don't think it makes a difference to the compiler, but I always write this-> because I believe it makes the code self-documenting.

Disambiguation: in case you have another similar naming function/variable in the same namespace? I've never seen usage for any other reason.

I prefer it without the explicit this pointer as well. For method calls it doesn't add a lot of value, but it helps distinguish local variables from member variables.

I can't quite remember the exact circumstances, but I've seen (very rare) instances where I had to write "this->membername" to successfully compile the code with GCC. All that I remember is that it was not in relation to ambiguity and therefore took me a while to figure out the solution. The same code compiled fine without using this-> in Visual Studio.

I will use it to call operators implicitly (the return and parameter types below are just dummies for making up the code).
struct F {
void operator[](int);
void operator()();
void f() {
(*this)[n];
(*this)();
}
void g() {
operator[](n);
operator()();
}
};
I do like the *this syntax more. It has a slightly different semantic, in that using *this will not hide non-member operator functions with the same name as a member, though.

Related

C++: What does "hide" means in overwrite method [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
name hiding and fragile base problem
I'm familiar with the rules involving member function hiding. Basically, a derived class with a function that has the same name as a base class function doesn't actually overload the base class function - it completely hides it.
struct Base
{
void foo(int x) const
{
}
};
struct Derived : public Base
{
void foo(const std::string& s) { }
};
int main()
{
Derived d;
d.foo("abc");
d.foo(123); // Will not compile! Base::foo is hidden!
}
So, you can get around this with a using declaration. But my question is, what is the reason for base class function hiding? Is this a "feature" or just a "mistake" by the standards committee? Is there some technical reason why the compiler can't look in the Base class for matching overloads when it doesn't find a match for d.foo(123)?
Name lookup works by looking in the current scope for matching names, if nothing is found then it looks in the enclosing scope, if nothing is found it looks in the enclosing scope, etc. until reaching the global namespace.
This isn't specific to classes, you get exactly the same name hiding here:
#include <iostream>
namespace outer
{
void foo(char c) { std::cout << "outer\n"; }
namespace inner
{
void foo(int i) { std::cout << "inner\n"; }
void bar() { foo('c'); }
}
}
int main()
{
outer::inner::bar();
}
Although outer::foo(char) is a better match for the call foo('c') name lookup stops after finding outer::inner::foo(int) (i.e. outer::foo(char) is hidden) and so the program prints inner.
If member function name weren't hidden that would mean name lookup in class scope behaved differently to non-class scope, which would be inconsistent and confusing, and make C++ even harder to learn.
So there's no technical reason the name lookup rules couldn't be changed, but they'd have to be changed for member functions and other types of name lookup, it would make compilers slower because they'd have to continue searching for names even after finding matching names in the current scope. Sensibly, if there's a name in the current scope it's probably the one you wanted. A call in a scope A probably wants to find names in that scope, e.g. if two functions are in the same namespace they're probably related (part of the same module or library) and so if one uses the name of the other it probably means to call the one in the same scope. If that's not what you want then use explicit qualification or a using declaration to tell the compiler the other name should be visible in that scope.
Is this a "feature" or just a "mistake" by the standards committee?
It's definitely not a mistake, since it's clearly stipulated in the standard. It's a feature.
Is there some technical reason why the compiler can't look in the Base class for matching overloads when it doesn't find a match for d.foo(123)?
Technically, a compiler could look in the base class. Technically. But if it did, it would break the rules set by the standard.
But my question is, what is the reason for base class function hiding?
Unless someone from the committee comes with an answer, I think we can only speculate. Basically, there were two options:
if I declare a function with the same name in a derived class, keep the base class's functions with the same name directly accessible through a derived class
don't
It could have been determined by flipping a coin (...ok, maybe not).
In general, what are the reasons for wanting a function with the same name as that of a base class? There's different functionality - where you'd more likely use polymorphism instead. For handling different cases (different parameters), and if these cases aren't present in the base class, a strategy pattern might be more appropriate to handle the job. So most likely function hiding comes in effect when you actually do want to hide the function. You're not happy with the base class implementation so you provide your own, with the option of using using, but only when you want to.
I think it's just a mechanism to make you think twice before having a function with the same name & different signature.
I believe #Lol4t0 is pretty much correct, but I'd state things much more strongly. If you allowed this, you'd end up with two possibilities: either make a lot of other changes throughout almost the entirety of the language, or else you end up with something almost completely broken.
The other changes you'd make to allow this to work would be to completely revamp how overloading is done -- you'd have to change at least the order of the steps that were taken, and probably the details of the steps themselves. Right now, the compiler looks up the name, then forms an overload set, resolves the overload, then checks access to the chosen overload.
To make this work even sort of well, you'd pretty much have to change that to check access first, and only add accessible functions to the overload set. With that, at least the example in #Lol4t0's answer could continue to compile, because Base::foo would never be added to the overload set.
That still means, however, that adding to the interface of the base class could cause serious problems. If Base didn't originally contain foo, and a public foo were added, then the call in main to d.foo() would suddenly do something entirely different, and (again) it would be entirely outside the control of whoever wrote Derived.
To cure that, you'd just about have to make a fairly fundamental change in the rules: prohibit implicit conversions of function arguments. Along with that, you'd change overload resolution so in case of a tie, the most derived/most local version of a function was favored over a less derived/outer scope. With those rules, the call to d.foo(5.0) could never resolve to Derived::foo(int) in the first place.
That, however, would only leave two possibilities: either calls to free functions would have different rules than calls to member functions (implicit conversions allowed only for free functions) or else all compatibility with C would be discarded entirely (i.e., also prohibit implicit conversions in all function arguments, which would break huge amounts of existing code).
To summarize: to change this without breaking the language entirely, you'd have to make quite a few other changes as well. It would almost certainly be possible to create a language that worked that way, but by the time you were done it wouldn't be C++ with one minor change -- it would be an entirely different language that wasn't much like C++ or C, or much of anything else.
I can only propose, that this decision was made to make things simpler.
Imagine, that derived function will overload base one. Then, does the following code should generate compilation error, or use Deriveds function?
struct Base
{
private:
void foo(float);
}
struct Derived: public Base
{
public:
void foo(int);
}
int main()
{
Derived d;
d.foo(5.0f);
}
According to existing behavior of overloads this should generate error.
Now imagine, in the first version Base had no foo(float). In second version it appears. Now changing the realization of base class breaks interface of derived.
If you are developer of Derived and cannot influence developers of Base and a lot of clients use your interface, you are in a bad situation now.

Reason for C++ member function hiding [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
name hiding and fragile base problem
I'm familiar with the rules involving member function hiding. Basically, a derived class with a function that has the same name as a base class function doesn't actually overload the base class function - it completely hides it.
struct Base
{
void foo(int x) const
{
}
};
struct Derived : public Base
{
void foo(const std::string& s) { }
};
int main()
{
Derived d;
d.foo("abc");
d.foo(123); // Will not compile! Base::foo is hidden!
}
So, you can get around this with a using declaration. But my question is, what is the reason for base class function hiding? Is this a "feature" or just a "mistake" by the standards committee? Is there some technical reason why the compiler can't look in the Base class for matching overloads when it doesn't find a match for d.foo(123)?
Name lookup works by looking in the current scope for matching names, if nothing is found then it looks in the enclosing scope, if nothing is found it looks in the enclosing scope, etc. until reaching the global namespace.
This isn't specific to classes, you get exactly the same name hiding here:
#include <iostream>
namespace outer
{
void foo(char c) { std::cout << "outer\n"; }
namespace inner
{
void foo(int i) { std::cout << "inner\n"; }
void bar() { foo('c'); }
}
}
int main()
{
outer::inner::bar();
}
Although outer::foo(char) is a better match for the call foo('c') name lookup stops after finding outer::inner::foo(int) (i.e. outer::foo(char) is hidden) and so the program prints inner.
If member function name weren't hidden that would mean name lookup in class scope behaved differently to non-class scope, which would be inconsistent and confusing, and make C++ even harder to learn.
So there's no technical reason the name lookup rules couldn't be changed, but they'd have to be changed for member functions and other types of name lookup, it would make compilers slower because they'd have to continue searching for names even after finding matching names in the current scope. Sensibly, if there's a name in the current scope it's probably the one you wanted. A call in a scope A probably wants to find names in that scope, e.g. if two functions are in the same namespace they're probably related (part of the same module or library) and so if one uses the name of the other it probably means to call the one in the same scope. If that's not what you want then use explicit qualification or a using declaration to tell the compiler the other name should be visible in that scope.
Is this a "feature" or just a "mistake" by the standards committee?
It's definitely not a mistake, since it's clearly stipulated in the standard. It's a feature.
Is there some technical reason why the compiler can't look in the Base class for matching overloads when it doesn't find a match for d.foo(123)?
Technically, a compiler could look in the base class. Technically. But if it did, it would break the rules set by the standard.
But my question is, what is the reason for base class function hiding?
Unless someone from the committee comes with an answer, I think we can only speculate. Basically, there were two options:
if I declare a function with the same name in a derived class, keep the base class's functions with the same name directly accessible through a derived class
don't
It could have been determined by flipping a coin (...ok, maybe not).
In general, what are the reasons for wanting a function with the same name as that of a base class? There's different functionality - where you'd more likely use polymorphism instead. For handling different cases (different parameters), and if these cases aren't present in the base class, a strategy pattern might be more appropriate to handle the job. So most likely function hiding comes in effect when you actually do want to hide the function. You're not happy with the base class implementation so you provide your own, with the option of using using, but only when you want to.
I think it's just a mechanism to make you think twice before having a function with the same name & different signature.
I believe #Lol4t0 is pretty much correct, but I'd state things much more strongly. If you allowed this, you'd end up with two possibilities: either make a lot of other changes throughout almost the entirety of the language, or else you end up with something almost completely broken.
The other changes you'd make to allow this to work would be to completely revamp how overloading is done -- you'd have to change at least the order of the steps that were taken, and probably the details of the steps themselves. Right now, the compiler looks up the name, then forms an overload set, resolves the overload, then checks access to the chosen overload.
To make this work even sort of well, you'd pretty much have to change that to check access first, and only add accessible functions to the overload set. With that, at least the example in #Lol4t0's answer could continue to compile, because Base::foo would never be added to the overload set.
That still means, however, that adding to the interface of the base class could cause serious problems. If Base didn't originally contain foo, and a public foo were added, then the call in main to d.foo() would suddenly do something entirely different, and (again) it would be entirely outside the control of whoever wrote Derived.
To cure that, you'd just about have to make a fairly fundamental change in the rules: prohibit implicit conversions of function arguments. Along with that, you'd change overload resolution so in case of a tie, the most derived/most local version of a function was favored over a less derived/outer scope. With those rules, the call to d.foo(5.0) could never resolve to Derived::foo(int) in the first place.
That, however, would only leave two possibilities: either calls to free functions would have different rules than calls to member functions (implicit conversions allowed only for free functions) or else all compatibility with C would be discarded entirely (i.e., also prohibit implicit conversions in all function arguments, which would break huge amounts of existing code).
To summarize: to change this without breaking the language entirely, you'd have to make quite a few other changes as well. It would almost certainly be possible to create a language that worked that way, but by the time you were done it wouldn't be C++ with one minor change -- it would be an entirely different language that wasn't much like C++ or C, or much of anything else.
I can only propose, that this decision was made to make things simpler.
Imagine, that derived function will overload base one. Then, does the following code should generate compilation error, or use Deriveds function?
struct Base
{
private:
void foo(float);
}
struct Derived: public Base
{
public:
void foo(int);
}
int main()
{
Derived d;
d.foo(5.0f);
}
According to existing behavior of overloads this should generate error.
Now imagine, in the first version Base had no foo(float). In second version it appears. Now changing the realization of base class breaks interface of derived.
If you are developer of Derived and cannot influence developers of Base and a lot of clients use your interface, you are in a bad situation now.

Why field inside a local class cannot be static?

void foo (int x)
{
struct A { static const int d = 0; }; // error
}
Other than the reference from standard, is there any motivation behind this to disallow static field inside an inner class ?
error: field `foo(int)::A::d' in local class cannot be static
Edit: However, static member functions are allowed. I have one use case for such scenario. Suppose I want foo() to be called only for PODs then I can implement it like,
template<typename T>
void foo (T x)
{
struct A { static const T d = 0; }; // many compilers allow double, float etc.
}
foo() should pass for PODs only (if static is allowed) and not for other data types. This is just one use case which comes to my mind.
Because, static members of a class need to be defined in global a scope, e.g.
foo.h
class A {
static int dude;
};
foo.cpp
int A::dude = 314;
Since the scope inside void foo(int x) is local to that function, there is no scope to define its static member[s].
Magnus Skog has given the real answer: a static data member is just a declaration; the object must be defined elsewhere, at namespace scope, and the class definition isn't visible at namespace scope.
Note that this restriction only applies to static data members. Which means that there is a simple work-around:
class Local
{
static int& static_i()
{
static int value;
return value;
}
};
This provides you with exactly the same functionality, at the cost of
using the function syntax to access it.
Because nobody saw any need for it ?
[edit]: static variables need be defined only once, generally outside of the class (except for built-ins). Allowing them within a local class would require designing a way to define them also. [/edit]
Any feature added to a language has a cost:
it must be implemented by the compiler
it must be maintained in the compiler (and may introduce bugs, even in other features)
it lives in the compiler (and thus may cause some slow down even when unused)
Sometimes, not implementing a feature is the right decision.
Local functions, and classes, add difficulty already to the language, for little gain: they can be avoided with static functions and unnamed namespaces.
Frankly, if I had to make the decision, I'd remove them entirely: they just clutter the grammar.
A single example: The Most Vexing Parse.
I think this is the same naming problem that has prevented us from using local types in template instantiations.
The name foo()::A::d is not a good name for the linker to resolve, so how should it find the definition of the static member? What if there is another struct A in function baz()?
Interesting question, but I have difficulty understanding why you'd want a static member in a local class. Statics are typically used to maintain state across program flow, but in this case wouldn't it be better to use a static variable whose scope was foo()?
If I had to guess why the restriction exists, I'd say it was something to do with the difficulty for the compiler in knowing when to perform the static initialisation. The C++ standards docs might provide a more formal justification.
Just because.
One annoying thing about C++ is that there's a strong dependence on a "global context" concept where everything must be uniquely named. Even the nested namespaces machinery is just string trickery.
I suppose (just a wild guess) that one serious technical issue is working with linkers that were designed for C and that just got some tweak to get them working with C++ (and C++ code needs C interoperability).
It would be nice to be able to get any C++ code and "wrap it" to be able to use it without conflicts in a larger project, but this is not the case because of linkage problems. I don't think there is any reasonable philosophical reason for forbidding statics or non-inline methods (or even nested functions) at the function level but this is what we got (for now).
Even the declaration/definition duality with all its annoying verbosity and implications is just about implementation problems (and to give the ability to sell usable object code without providing the source, something that is now a lot less popular for good reasons).

Using a Template to Expose a Private Typedef

I have a class that contains a private typedef and several member
functions:
class Foo
{
private:
typedef std::blahblah FooPart;
FooPart m_fooPart;
...
public:
int someFn1();
int someFn2();
};
Several member functions need to use m_fooPart in a similar way, so I
want to put that in a function. I put helper functions in the anonymous
namespace whenever I can, but in this case, they need to know what
FooPart is. So, I've done this:
namespace
{
template <typename T>
int helperFn(const T& foopart, int index)
{
...
return foopart.fn(index);
}
}
int Foo::someFn1()
{
...
return helperFn(m_fooPart, ix);
}
By forcing the compiler to produce the FooPart type, am I still in the
land of well-defined behavior? Is there a more elegant way of
accomplishing this that doesn't increase the size of Foo or make public
what is now private?
Yes, that approach produces well-defined, standards-compliant behavior.
That said, adding member functions to a class does not increase the size of a class (assuming you mean the result of the sizeof operator), so I'm not sure what drawback you perceive in just making the helper function a private member of Foo.
Simple answer: make the typedef public.
That will leak a minor detail of implementation (the actual internal type), but because it is typedefed you can redefine it at any time and it should be fine.
A little less simple: befriend the helper function, providing access to your internal type.
The problem with this second approach is that you are not only granting access to the typedef, but also to all the private parts of your class, and that might not be the best idea. At any rate, since this is an internal helper function, it is under your own control, and it should be fine. (Now that I think of it, you might want to declare the function in a named namespace, for the friend declaration to succeed)
Even less simple: Create a separate typedef inside the implementation file, and ensure that they are synchronized.
You can ensure that the types are the same with a small bit of metaprogramming, with a same_type<T,U> template that will provide a true value if the two types are the same and false otherwise. A static assert will trigger an error if the typedef changes in only one place
Back to simple again: provide the typedef or use the type directly without the static assert.
You are calling a function (this should not be a template as in your code) and passing a reference. If the typedef changes in the class, the call will fail and the compiler will tell you.
I would go for the last option, while it may look a little rough and less delicate than the others, the fact is that this is only an implementation detail that is not used by others, you are under full control of the code and well, simple is better.
EDIT, after the comment.
I started writing this as a comment, but it became too long, so I am adding it to the answer.
There is nothing wrong in that solution by itself, other than you are making a function generic unnecessarily and some error messages in the future might not be as simple as they could be with a non-generic signature. Note that the template will not expose the typedef (as the question title suggests) but rather it will make the compiler infer the type at the place of call.
If you change the typedef, instead of getting an error saying that the arguments to helperFn cannot be matched against the existing function, the type will be inferred and the function matched, but you will get an error deeper in helperFn if you use a property of the type that is no longer present. Or worse, you might not even get an error if it is the semantics of the type that have changed.
Consider that the typedef is of a std::list<X>, and that in the function you are iterating over it with this simple correct for loop:
for (typename T::iterator it=x.begin(), end=x.end(); it != end; ) {
if ( condition(*it) )
it = x.erase(it);
else
++it;
}
Can you catch the effect that changing the typedef to std::vector<X> will have? The compiler cannot even if the code is now incorrect. Whether writing the for loop like that is a good idea, or why is it not just using the erase-remove idiom are different issues (as a matter of fact the previous loop is arguably better than erase-remove for a list), the concrete situation is that the semantics have changed, and because the type is syntactically compatible with the previous one the compiler will not notice that the code is wrong, it will not point you to that function and chances are that you will not review/rewrite it.
I guess this is the idea of generic programming - do stuff with a part of Foo without knowing its type.
A more "traditional" (strongly-typed, boring, readable, code-duplicating - you name it) way would be to mention the type explicitly:
int helperFn(const std::blahblah& foopart, int index)
{
...
return foopart.fn(index);
}

C++ - calling methods from outside the class

I have couple questions regarding some C++ rules.
Why am I able to call a function/method from outside the class in the namespace when I include the return type? (look at the namespace test2::testclass2 in the code below) i.e. this works:
bool b = testclass1::foo<int>(2);
whereas this doesn't: - (it doesn't even compile - compiler throws that this is function redeclaration)
testclass1::foo<int>(2);
C++ complains that it is a function redeclaration. Is that so?
This line:
bool b = testclass1::foo<int>(2);
gets called first before anything else. Is this because static methods get created always first before anything else in C++?
Where can I find those rules? I have a few C++ books at home, so if someone would be kind enough to either point out a book (and chapter or page) or direct me to a website I would greatly appreciate it.
Here below is the sample (partial) code that I tested at home with Visual Studio 2008:
class testclass1
{
public:
testclass1(void);
~testclass1(void);
template<class A> static bool foo(int i)
{
std::cout <<"in static foo";
return true;
}
};
namespace test2
{
class testclass2
{
public:
testclass2(void);
~testclass2(void);
};
bool b = testclass1::foo<int>(2);
}
EDIT:
A few people mentioned that I need to call this inside the function and this will work without any problem.
I understand that; the only reason I asked this question is because I saw this code somewhere (in someone's elses project) and was wondering how and why this works. Since I never really seen anyone doing it before.
Also, this is used (in multiple places) as a way to call and instantiate a large number of classes like this via those function calls (that are outside). They get called first before anything else is instantiated.
C++ is not Python. You write statements in functions and execution starts from the main method. The reason bool b = ... happens to work is that it's defining the global variable b and the function call is merely the initialization expression.
Definitions can exist outside functions while other statements can only exist inside a function body.
Why am I able to call a function/method from outside the class in the namespace when I include the return type? (look at the namespace test2::testclass2)
Your declaration of b is not inside a function, so you are declaring a global variable. If you were inside a function's scope, your second statement would work, but outside a function it makes no sense.
This also answers your second question.
Of course, you wouldn't be allowed to call it this way (i.e. not as a method of an object) if it weren't a static member function.
You can find the rules on e.g. Koenig lookup and template in the standard documentation -- good luck with navigating that! You're not mentioning which compiler you are testing, but I'm not entirely sure it's compliant!
As Mehrdad points out, you're declaring and initializing a global variable within the test2 namespace: this has nothing to do with static methods.
if you write this inside a function like below then it works without a problem. As mentioned above, you need to call these functions from within a function unless you are using the function to initialize a global variable ...
int main()
{
testclass1::foo<int>(2);
return 0;
}
1. First, a helpful correction: you said "...when I include the return type". I think you might be misunderstanding what the <int> part of testclass1::foo<int>(2) does. It doesn't (necessarily) specify the return type, it just provides a value for the template argument "A".
You could have chosen to use A as the return type, but you have the return type hard-coded to "bool".
Basically, for the function as you have written it you will always need to have the <> on it in order to call it. C++ does allow you to omit the <args> off the function when the type can be deduced from the function arguments; in order to get it to do that you have to use the type argument A in your function arguments. For instance if you declared the function this way instead then you could call it without the <>:
template<class A> static bool foo(A i);
In which case it you could call "foo(2)" and it would deduce A to be "int" from the number two.
On the other hand there isn't any way to make it deduce anything based on what you assign the function to. For template argument deduction it only looks at the arguments to the function, not what is done with the result of calling the function. So in:
bool b = testclass1::foo(2);
There is no way to get it to deduce "bool" from that, not even if you made A the return type.
So why doesn't the compiler just tell you "you needed to use <> on the function"? Even though you declared foo once as a template function, you could have also overloaded it with a non-template version too. So the compiler doesn't just automatically assume that you're trying to call a template function when you leave the <> off the call. Unfortunately having NOT assumed you were calling template-foo and not seeing any other declaration for foo, the compiler then falls back on an old C style rule where for a function that takes an int and returns an int, in a very old dialect of C you didn't need to declare that kind of before using it. So the compiler assumed THAT was what you wanted - but then it notices that template-foo and old-crufty-C-foo both take an int parameter, and realizes it wouldn't be able to tell the difference between them. So then it says you can't declare foo. This is why C++ compilers are notorious for giving bad error messages - by the time the error is reported the compiler may have gone completely off the rails and be talking about something that is three or four levels removed from your actual code!
2. Yes you're exactly right.
3. I find that the C++ references and whitepapers that IBM makes available online are the most informative. Here's a link to the section about templates: C++ Templates