This code compiles (Using GCC / C++11):
void doStuff_HELPER(int a) { /**/ }
class SomeClass{
public:
void doStuff() {doStuff_HELPER( 10);}
};
This doesn't:
void doStuff(int a) { /**/ }
class SomeClass{
public:
void doStuff() {doStuff( 10);}
};
It doesn't say it's ambiguous or it can't be overloaded or anything it just says: "no matching function SomeClass::doStuff(int)", "candidate: void SomeClass::doStuff()". Is this the correct behavior? What does the standard say about this?
(Also, what is the best practice for such helper functions? Should they be put into a separate namespace maybe?)
Call it explicitly specifying scope: ::doStuff(10);
You should use the Scope Resolution Operator to resolve this. Using ::doStuff(10) instead of doStuff(10) tells the compiler to look in the global namespace to resolve the name collision.
Related
I want to give a static member another name, so it can be linked in a vector table which is elsewhere predefined. The idea is simply to call my static method from the vector table. This works quite well with static methods from non templated class if the declaration and definition is divided.
But I want to have a templated class, so I have no idea how I can write that.
Q1: Why asm("name") did not work for definitions? Any tricks here?
Q2: How can I write a templated definition of a static class method? The problem is that I have no call from my source to it, because it should only be linked in a vector table. Also I have no knowledge at this place with which parameter it will be instantiated.
//non templated variant
class Bla
{
public:
// with attributes it seems to work
void f1() __attribute__((deprecated))
{
}
void f2() __asm__("__newName_f2"); // works
// compiles without error or warning, but no renaming happens!
void f3() __asm__("__newName_f3") __attribute__(( __used__, __externally_visible__)) {}
};
void Bla::f2() {} // definition for renamed function, OK works!
template <typename T>
class Blub
{
void b1() __asm__("__blub_b1") ;
};
// How to write a templated method?
// The instance must be visible without a call,
// because it should be linked in a vector table
template <typename T>
void Blub<T>::b1() {}
int main()
{
Bla bla;
Blub<int> blub;
}
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.
This doesn't compile,
#include <boost/intrusive_ptr.hpp>
class X
{
public:
void intrusive_ptr_add_ref(X* blah)
{
}
void intrusive_ptr_release(X * blah)
{
}
};
int main()
{
boost::intrusive_ptr<X> ex(new X);
}
But this does :
#include <boost/intrusive_ptr.hpp>
class X
{
public:
friend void intrusive_ptr_add_ref(X* blah)
{
}
friend void intrusive_ptr_release(X * blah)
{
}
};
int main()
{
boost::intrusive_ptr<X> ex(new X);
}
and this :
#include <boost/intrusive_ptr.hpp>
class X
{
public:
};
void intrusive_ptr_add_ref(X* blah)
{
}
void intrusive_ptr_release(X * blah)
{
}
int main()
{
boost::intrusive_ptr<X> ex(new X);
}
I suppose it has something to do with SFINAE (which I haven't as of yet bothered to understand) ? Does the friend qualifier put the defined function as a free function in the enclosed namespace ?
edit
Whoever removed their post, member functions non-friend as add_ref and release (these specific member functions are not mentioned in the documention...) did solve the problem. What happens with the nested definition with the friend qualifier ?
From the documentation of boost::intrusive_ptr:
Every new intrusive_ptr instance increments the reference count by using an unqualified call to the function intrusive_ptr_add_ref, passing it the pointer as an argument. Similarly, when an intrusive_ptr is destroyed, it calls intrusive_ptr_release; this function is responsible for destroying the object when its reference count drops to zero. The user is expected to provide suitable definitions of these two functions. On compilers that support argument-dependent lookup, intrusive_ptr_add_ref and intrusive_ptr_release should be defined in the namespace that corresponds to their parameter; otherwise, the definitions need to go in namespace boost.
This means that intrusive_ptr_add_ref and intrusive_ptr_release should not be member functions, but free functions (friend functions behave as such). Furthermore they are called without qualification, so they should be in the global namespace or somewhere found by ADL.
Edit: To your question about nested definitions with friend qualifier:
friend functions are defined as non memberfunctions, so friend void intrusive_ptr_add_ref(X* blah) will be called as intrusive_ptr_add_ref(my_x_ptr) instead of as my_x_ptr->intrusive_ptr_add_ref().
#include <iostream>
using namespace std;
class CClass
{
private:
friend class CFriend;
static void privateFunc(){std::cout << "privateFunc" << std::endl;};
};
class CFriend
{
public:
void privateFunc(){privateFunc();};
};
int main(int argc, char* argv[])
{
CFriend b;
b.privateFunc();
return 0;
}
This code compiles, but using the gcc-compiler or http://www.ideone.com/ the program crashes. Is that a compiler error or do I need to understand more about friend classes?
You've created infinite recursion:
void privateFunc(){privateFunc();};
Use instead:
void privateFunc(){CClass::privateFunc();};
There's nothing wrong with friend declaration.
Infinite recursion in your object, creating a Stack Overflow !!!
You must explicitely call your friend class :
void privateFunc(){CClass::privateFunc();};
You have the function called privateFunc() in CFriend class as well. This means when inside that function you call privateFunc() it will call itself (how should it know you mean the other class) thus entering a recursive infinite loop.
You mean
void privateFunc()
{
CClass::privateFunc();
}
using CClass:: to specify completely the name of the function you mean.
It is crashing because of stack overflow you would beed scope resolution to call static function
class CFriend
{
public:
void privateFunc(){CClass::privateFunc();};
};
You have a stack overflow from an infinitely recursive function. CFriend::privateFunc is calling itself. Change it to void privateFunc() {CClass::privateFunc();}
Scope distinctions, public, private, protected and friend, have not runtime consequences at all. They are strictly for the compilier to decide what is legal or not. You could #define private public and the resulting executable wouldn't change.
I was trying to write up a class in c++, and I came across a rather odd problem: calling outside functions inside of a class that have the same name as the class. It's kinda confusing, so here's an example:
void A(char* D) {
printf(D);
}
class A
{
public:
A(int B);
void C();
};
A::A(int B) {
// something here
}
void A::C() {
A("Hello, World.");
}
The compiler complains at the second to last line that it can't find a function A(char*), because it is inside the class, and the constructor has the same name as the function. I could write another function outside, like:
ousideA(char* D) {
A(D);
}
And then call outsideA inside of A::C, but this seems like a silly solution to the problem. Anyone know of a more proper way to solve this?
::A("Hello, world.");
should work fine. Basically it is saying "use the A found in the global namespace"
Use the scope resolution operator :: to access the name from the global scope:
void A::C() {
::A("Hello, world.");
}
I suggest you use namespaces. Put your class in a different namespace than the function.
namespace my_namespace1
{
void A() {}
}
namespace my_namespace2
{
struct A {};
}
int main()
{
my_namespace1::A();
my_namespace2::A my_a;
}
Of course, the real question is, why do you have a class and a function with a different name? A good easy rule is to make classes named WithABeginningCapitalLetter and functions withoutOne. Then you will never have this problem. Of course, the STL doesn't do this...