I have the following piece of code:
How do I call a member function in scope exit.
class A
{
public:
void foo();
void bar();
};
void A::foo()
{
BOOST_SCOPE_EXIT(void)
{
bar(); // Does not compile
}
BOOST_SCOPE_EXIT_END
}
void A::bar() {}
void foo4()
{
A a;
a.foo();
}
Err message
boost_scope_exit.cpp: In static member function ‘static void
A::foo()::boost_se_guard_t_71::boost_se_body()’:
boost_scope_exit.cpp:73:13: error: cannot call member function ‘void
A::bar()’ without object
bar(); // Does not compile
^
How can I call a member function from scope exit.
Found a answer in the boost documentation:
Boost docs
Just search for "Capturing The Object this"
Your code will work if you make bar static (and call A::bar()).
If that's not an option, it looks like you need to capture the this pointer
using the special symbol this_ (note the trailing underscore).
BOOST_SCOPE_EXIT(this_)
{
this_->bar(); // note trailing underscore on this_
}
BOOST_SCOPE_EXIT_END
Related
Say I have a class as follows in a header file:
class A {
public:
void foo();
}
The function foo needs to call another "helper" function named bar. Bar isn't needed anywhere else other than inside foo. Should it be defined statically outside the scope of A:
(source file)
static void bar() { ... }
void A::foo() {
bar(); ...
}
or within the class?
(header)
class A {
public:
void foo();
private:
void bar();
}
(souce)
void A::bar() { ... }
void A::foo() {
bar(); ...
}
Bar isn't needed anywhere else other than inside foo.
If so then bar should be a private member function of class A - there is no need to define bar in global namespace.
static void bar() { ... } // not needed
instead use:
void A::bar() { ... } // <- bar should be private member function
Generally, you should only allow access to the internals of a class when necessary. Placing the function outside the class and restricting its scope--either as a static function or within an anonymous namespace, would be best. That way, you're not polluting the global namespace and you're not allowing unnecessary access to class internals.
For example, you can, in the class's cpp file, have:
namespace {
void bar() {.....}
}
and that helper function is then available for your class methods in the same cpp file.
Static functions in the cpp file would also have file scope only, but I find the static keyword to be confusing when used that way.
This seems a bit strange to me. Since a static method can have an instance of the class, one naturally expects that the compiler should not allow calling static methods inside the constructor. But I have tested the following code with every compiler and ironically, none of them gave me a single warning. Although in execution time they all throw exceptions. Am I missing something here?
#include <iostream>
class Foo
{
public:
inline Foo()
{
std::cout << "testing: var = " << bar() - 1 << '\n';
}
~Foo(){}
static int bar()
{
Foo f;
f.var = 10;
return f.test();
}
private:
int var;
int test()
{
return var + 1;
}
};
int main()
{
Foo foo;
return 0;
}
Live example
It is not illegal to call static functions from within the constructor. Only, you are getting a stack overflow, if you do it like you do. This results in
Foo() calls bar();
bar() calls Foo();
Foo() calls bar();
bar() calls Foo();
...
Until no stack is left.
This is exactly the same as if you had:
void f1();
void f2()
{
f1();
}
void f1()
{
f2();
}
int main(int, char*[])
{
f1();
return 0;
}
Only two global functions, nothing more. Would have been all the same in C, too (but you have do declare void f(void) there), or Java, C#, perl, python, ...
What warnings are you expecting? What you've written is an infinite recursion which has nothing to do with static member functions. You can do it with any other function inside or outside a class.
Static functions are not much different from the free ones. So free functions should also be banned from constructor? There is no point in forbidding to call static functions from constructors.
There is no reason not to call a static (or in fact a non-static) member function in a constructor (although it is not recommended to call virtual functions).
This code does not compile:
class A;
void foo(A&) {
}
class A {
void foo() {
foo(*this); ///This does not compile
}
};
Errors:
error: no matching function for call to 'A::foo(A&)'
foo(*this);
^
note: candidate is:
note: void A::foo()
This can be solved by calling ::foo(*this);
However, let's consider the case we are in a namespace:
namespace bar {
class A;
void foo(A&) {
}
class A {
void foo() {
foo(*this); ///This does not compile
}
};
}
Is there any other way than calling explicitly bar::foo(*this);? I mean, is there any way to look up names in the next surrounding declarative region, i.e. the containing bar namespace?
The use case is similar to what seen here.
I mean, is there any way to look up names in the next surrounding declarative region,
i.e. the containing bar namespace?
No.
You can sort of do it the other way around:
void foo() {
using bar::foo;
foo(*this); /// OK now
}
Not within the method itself. However, you can do this in the .cpp file:
namespace bar {
namespace {
auto outerFoo = foo;
}
void A::foo() {
outerFoo(*this);
}
}
Note that the name outerFoo is a hidden implementation detail which cannot cause name collisions (since it's in an anonymous namespace).
I have a method inside the Foo class that needs to call the free floating function freeFloat. However, calling it results in a out of scope error.
Foo.cpp: In member function ‘virtual bool Foo::method()’:
Foo.cpp:351:24: error: ‘freeFloat’ was not declared in this scope
freeFloat();
The structure of the code looks something like this:
class Foo {
public:
virtual void method() {
freeFloat();
}
};
int main(){
}
bool freeFloat(){
}
Can this be done? If so, is it considered poor practice or in most cases OK? Is there a better placement for each method?
The function shall be declared before the class definition if it refers to the function.
Any name in C++ shall be declared before its using.
You need to declare the function before calling it....
bool freeFloat();
class Foo {
public:
virtual void method() {
freeFloat();
}
};
int main(){
}
bool freeFloat(){
}
You need to declare freeFloat before you can call it. Either move the function definition to the top or add:
bool freeFloat();
to the top.
If I have a class definition
class myClass
{
void x();
};
void myClass::x()
{
hello(); // error: ‘hello’ was not declared in this scope
}
void hello()
{
cout << "Hello\n" << endl;
}
How can I call a function defined outside the scope of a class and located in the same file ? I know that I can use Namespace::function but I am not sure in this case what I should use for Namespace
You must at least declare it (if not define it) before its use.
Usually, this is done in an anonymous namespace if the function's functionality is only used in that translation unit:
class myClass
{
void x();
};
namespace
{
void hello()
{
cout << "Hello\n" << endl;
}
}
void myClass::x()
{
hello(); // error: ‘hello’ was not declared in this scope
}
This gives the function internal linkage (similar to declaring it static) and is only available in that TU.
Define the hello function in the file ahead of where it's being used - before method x - or supply a function prototype ahead of where it's being used:
void hello(); // function definition is later in the file
void myClass::x()
{
hello();
}