About function declarations in functions [duplicate] - c++

This question already has answers here:
Is there a use for function declarations inside functions?
(4 answers)
C++: Why does function declaration is allowed inside another function but not function definition?
(1 answer)
Why does a function declaration within another function compile and what does it do?
(2 answers)
Closed 7 months ago.
We can have function declarations inside of function bodies:
void f(double) {
cout << "f(double) called";
}
void f(int) {
cout << "f(int) called";
}
void g() {
void f(double); //Functions declared in non-namespace scopes do not overload
f(1); //Therefore, f(1) will call f(double)
}
This can be done in order to hide a function such as f(int) in this case, but my question is: Is this really the only reason why it is possible to declare a function inside of another?
Or in other words:
Does the possibility of declaring a function inside of a function exist for the sole purpose of hiding a function?

This can also be used to limit the visibility of a function declaration to only one specific function. For example:
file1.cpp:
#include <iostream>
void f(double d) {
std::cout << d << '\n';
}
file2.cpp:
int main() {
void f(double);
f(1); // prints 1
}
void g() {
f(2); // error: 'f' was not declared in this scope
}

Related

class with friend rather than forward declaration,: which compiler is correct [duplicate]

This question already has answers here:
Friend method "not declared in this scope" in C++
(1 answer)
Error: 'Friend Member Function Name' was not declared in this scope
(3 answers)
Closed 3 years ago.
I have this simple C++ program:
#include <iostream>
struct obj {
friend int f(int);
void m(int x) { std::cout << "f(" << x << ") = " << f(x) << std::endl; }
};
int main() {
obj o;
o.m(21);
}
int f(int x) {
return 2*x;
}
If I compile with the GNU C++ compiler g++, I get the error prog.cpp:7:55: error: 'f' was not declared in this scope
However, if I compile it with cl (and /W4) it compiles and executes fine.
I am not sure which compiler is correct.
From cppreference on friend declaration:
A name first declared in a friend declaration within class or class template X becomes a member of the innermost enclosing namespace of X, but is not visible for lookup (except argument-dependent lookup that considers X) unless a matching declaration at the namespace scope is provided
A matching declaration at global scope is provided, but only after the definition of obj::m(). I think it's correct to refuse the call to f at this point. You can see the effect e.g. this compiles with both gcc and clang,
int f(int);
class obj { /* as before... */ };
and so does this:
struct obj {
friend int f(int);
void m(int x);
};
int f(int);
void obj::m(int x) { std::cout << "f(" << x << ") = " << f(x) << std::endl; }

C++ error: 'count_of_function_calls' was not declared in this scope

hi I am new to c++ and I am stuck in a question. I am a beginner, please help me, that you.
#include <iostream>
using namespace std;
int dostuff ()
{
return 2 + 3;
}
void fun ()
{
count_of_function_calls++;
}
int main()
{
void fun ();
void fun ();
void fun();
cout << "Function fun was called" << count_of_function_calls << "times";
}
Many, many problems, you should definitely read a C++ book or reread some tutorials
Where did you define count_of_function_calls?
Nowhere, that's why the compiler is complaining. You always have to declare variables before you use them:
int count_of_function_calls = 0;
Note that in your case, because you want to value of count_of_function_calls to be incremented for each function call, you should declare it as a global variable (this is not recommended, consider using something else).
A global variable is declared outside of any scope, in your case, you could for example defined it just above void fun ().
void fun (); declares a function (called fun), taking no arguments and returning void. It doesn't call the function fun. If you want to call a function, you don't have to specify the return type:
//Call function 'fun'
fun();
I think you forgot to define global variable count_of_function_calls
For example
#include <iostream>
using namespace std;
int count_of_function_calls;
int dostuff ()
{
return 2 + 3;
}
void fun ()
{
count_of_function_calls++;
}
//...
And the function calls must look like
fun();
This
void fun ();
is a function declaration. It is not a call of the function.

C++11 multithreading with class member function [duplicate]

This question already has answers here:
Start thread with member function
(5 answers)
Closed 7 years ago.
I want to use multithreading in C++11 to call a class member function in its own thread. I have been able to get this to work with a global function:
#include <thread>
#include <iostream>
void Alpha(int x)
{
while (true)
{
std::cout << x << std::endl;
}
}
int main()
{
std::thread alpha_thread(Alpha, 5);
alpha_thread.join();
return 0;
}
However, I cannot get it to compile with a class member function:
#include <thread>
#include <iostream>
class Beta
{
public:
void Gamma(int y)
{
while (true)
{
std::cout << y << std::endl;
}
}
};
int main()
{
Beta my_beta;
std::thread gamma_thread(my_beta.Gamma, 5);
gamma_thread.join();
return 0;
}
The compile error is:
no matching function for call to 'std::thread::thread(<unresolved overloaded function type>)'
std::thread gamma_thread(my_beta.Gamma, 5);
^
What am I doing wrong?
You need to pass two things: a pointer-to-member, and the object. You cannot call a non-static member function (like Gamma) in C++ without an object. The correct syntax would be:
std::thread gamma_thread(&Beta::Gamma, // the pointer-to-member
my_beta, // the object, could also be a pointer
5); // the argument
You can think of my_beta here as being the first argument to Gamma(), and 5 as the second.
You need to name the function, then pass the object on which to call it as an explicit implicit this parameter. :)
std::thread gamma_thread(&Beta::Gamma, my_beta, 5);
This is a bit of an abstraction leak, granted.
You have multiple problems in your program
As your compile error says, you need to pass the address of the function &Beta::Gamma.
You need to pass the object as a parameter considering this is an implicit parameter of a member function
Modified source
#include <thread>
#include <iostream>
class Beta
{
public:
void Gamma(int y)
{
while (true)
{
std::cout << y << std::endl;
}
}
};
int main()
{
Beta my_beta;
std::thread gamma_thread(&Beta::Gamma, my_beta, 5);
gamma_thread.join();
return 0;
}

Not able to call a function using function pointer [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to call a function using pointer-to-member-function
Analyzer.h
class Analyzer
{
public :
void viku();
void Bibek();
void vivek();
void (Analyzer::*point)();
Analyzer(){
}
~Analyzer(){
}
};
Analyzer.cpp
using namespace std
#include"Analyzer.h"
void Analyzer::viku(){
cout<<"Hello viku";
}
void Analyzer::vivek(){
point =&Analyzer::viku;
Bibek();
}
void Analyzer::Bibek(){
point();//Errror
cout<<"Bibek";
}
During compilation it shows the following error:
error C2064: term does not evaluate to a function taking 0 arguments.
Can anyone please tell me how to avoid this?
Pointers to member functions are different than normal function pointer. You need an instance to call them:
#include <iostream>
class A
{
public:
int foo()
{
std::cout << "A::foo here, you can have 42" << std::endl;
return 42;
}
};
int main ()
{
int (A::* point)() = &A::foo;
A a;
(a.*point)();
}
In your case, you'd need to do something like the following:
(this->*point)()

Function overload resolution trouble

Over the weekend, I had specific problem with function overload resolution that I can't seem to solve.
The code below is a distillation of the problem:
#include <iostream>
using namespace std;
template<typename T>
void f(const T& t)
{
cout << "In template function." << endl;
}
class C
{
public:
void f() { cout << "In class function." << endl; }
void g() { int i=0; f(i); }
void h() { int i=0; f<int>(i); }
void i() { extern void f(int); int i=0; f(i); }
};
int main()
{
cout << "Test" << endl;
C c;
c.i();
return 0;
}
1) C::g won't compile because the compiler won't try the template. It just complains that there is no C::f to match.
2) C::h won't compile for no reason that is obvious to me. The message is "expected primary-expression before 'int'"
3) C::i will compile, but (after commenting out g and h) it won't link to anything. I think I understand this: the extern is forcing the linker to look into another compilation unit, but any template definition would be in this compilation unit.
I would appreciate any clarification on the reasons for 1 and 2. Also, ultimately, can someone suggest a way to get this to work that doesn't involve creating another compilation unit?
Likely it is finding C::f instead of global f. Use ::f<int>(i).
Look here: http://ideone.com/zs9Ar
Output:
Test
In template function.
#include <iostream>
using namespace std;
template<typename T>
void f(const T& t)
{
cout << "In template function." << endl;
}
class C
{
public:
void f() { cout << "In class function." << endl; }
void g() { using ::f; int i=0; f(i); }
};
int main()
{
cout << "Test" << endl;
C c;
c.g();
return 0;
}
Names in a smaller scope hide names in an outer scope.
Use ::f to indicate global namespace.
In i() you declare a function called f, but indeed there is no definition (it is not the same as the template), so you get a linker error.
C++ is somewhat "greedy" when trying to find functions. As soon as it finds a matching function name in the current scope (in this case, class C) it stops and then tries to match the parameters. If the parameters don't match, it won't try additional scopes. I assume this was to keep compiler writers sane. That's why g doesn't compile.
The same thing applies to h. It sees a non-template function f in the class scope and gets confused. It thinks you're trying to do a < comparison against the function C::f.
In both cases you can use ::f to qualify the name to the global scope.
Functions with the same name will hide other functions of the same name when they have different scopes, even if they have different signatures.
Instead of using a template for the first f, you could just do f(int) and the result would be the same for #1(the C::f() hides the ::f(int)).
One solution is to add "::" before the name to force the global namespace.
Another solution would be to change the names.