Let's suppose I have a namespace Foo and I have declared a class Bar inside of it with a constructor inheriting a class Base with its constructor along with some other class Baz with a publicly accessible method boo():
namespace Foo {
class Baz {
public:
void boo();
};
class Base {
public:
Base();
};
class Bar: public Base {
public:
Bar();
};
}
Now I want to define the Bar constructor in my implementation as follows:
Foo::Bar::Bar(): Foo::Base::Base() {
Foo::Baz::boo();
}
It appears as though it's OK to write it down like this:
Foo::Bar::Bar(): Base() {
Baz::boo();
}
Meaning that once I specify the namespace in Foo::Bar::Bar() explicitly, there is no need to specify it later in the definition of this method.
Does it work like that everywhere from the explicit mentioning of the namespace up to the end of the definition?
If we look at your Bar constructor definition:
Foo::Bar::Bar(): Base() {
Baz::boo();
}
Once the declaration-part of the constructor (Foo:::Bar::Bar) have been read by the compiler, it knows the scope and it's no longer needed.
A more interesting example would be e.g.
namespace Foo
{
struct Baz {};
struct Bar
{
Baz fun(Baz);
};
}
Foo::Baz Foo::Bar::fun(Baz)
{
// Irrelevant...
}
Now, for the definition of the structure itself, Baz doesn't need any namespace-qualifier since it's defined in the namespace and all the symbols of the namespace is available directly.
The definition of the function fun is a different. Because it's not defined inside the namespace, we need to fully qualify the Baz structure for the return type. And the same for the actual function-name. But then like before once that part is read and parsed by the compiler, it knows the scope and knows that the argument Baz is really Foo::Baz.
You can read more about name lookup in this reference.
Related
I'm getting this strange problem which I don't know why happens. The first and second of the following code snippets compile, while the third does not:
Compiles:
class Foo {
public:
Foo() { Bar(); }
private:
class Bar {};
};
Compiles:
class Foo {
class Bar {}; // Or only forward declare here and define later
public:
Foo(Bar) {}
}
Does not compile:
class Foo {
public:
Foo(Bar) {}
private:
class Bar {};
};
What makes the third fail to compile while the first can?
Normally, in C++, you can only reference declarations that were previously made in the translation unit. However, within a class definition, the definition of member functions are allowed to reference declarations which are made later in the class. Basically, the compiler restructures your in-class definitions so that they work as though they were written just after the class.
But this is only true of the function definitions. The declaration of the function (including parameter types) isn't allowed to do this. They can only reference declarations that have already been made in file order.
So you can do this:
class Test
{
public:
void Func(int x) {Inner foo;}
private:
class Inner {};
};
But not this:
class Test
{
public:
void Func(Inner x) {}
private:
class Inner {};
};
First example does not expose anything about private Bar to the outside, while third does.
Third example is pretty much saying, that there exist some class Foo, which has constructor with single argument of type Bar. But Bar is unknown to the outside. Imagine calling such constructor.
Foo f{Foo::Bar{}};
Will result probably in something like Foo::Bar is inaccessible.
The more I program, the more I like the snake_case and the less the CamelCase. There is one particular inconvenience irritating me a bit: I do not like getters start from the get_ prefix, but that is not always possible without some extra work when using the snake_case. Consider, for instance, a getter for a member of enum type defined inside a class,
class bar
{
public:
enum class foo { a, b };
foo foo() const { return m_foo; }
void set_foo(foo new_foo) { m_foo = new_foo; }
private:
foo m_foo;
};
This won't compile since (if I understand correctly) enum foo is hidden in both the setter new_foo parameter type and the private m_foo member declaration by the prior foo() getter declaration. The obvious fix is to name the getter as get_foo, but as I said, I don't like it.
When I compile with Clang it suggests another "workaround":
error: must use 'enum' tag to refer to type 'foo' in this scope
void set_foo(foo new_foo) { m_foo = new_foo; }
^
enum
and the same for m_foo member. The following code indeed compiles fine
class bar
{
public:
enum class foo { a, b };
foo foo() const { return m_foo; }
void set_foo(enum foo new_foo) { m_foo = new_foo; }
private:
enum foo m_foo;
};
It looks like the elaborated type specifiers are even supposed to solve such kind of problems:
Elaborated type specifiers may be used to refer to a
previously-declared class name (class, struct, or union) or to a
previously-declared enum name even if the name was hidden by a
non-type declaration.
But is not that a misuse of a language feature? Have you ever seen anything like that in libraries that use snake_case, such as, for instance, the Standard Library or Boost, or write it yourself?
I am working on a project and I am facing a little bit strange code which I cannot understand why and how can this happen !
I have a class Foo and Baz, and Foo has a non-static method that is called from Baz class without instantiating Foo:
class Foo {
public:
void qux(int a, int b);
};
class Baz {
public:
void bar(void);
};
void Baz::bar(void){
Foo::qux(2,3); // This should not happen as qux is not a static method !!
}
The only way that would work is if Baz was derived from Foo at some level.
Or, of course, Foo bears a different meaning in that scope (via a using, typedef, define or other).
If neither apply, your compiler is seriously broken.
This can happen in case of Baz is inherited from Foo.
In this case you can call method of the base class directly in the form that you mentioned:
void Baz::bar(void){
Foo::qux(2,3);
}
I got a situation like this:
struct Foo
{
void Barry() { }
};
struct Bar : private Foo
{
template <class F> void Bleh(F Func) { Func(); }
};
struct Fooey : public Bar
{
void Blah() { Foo f; Bar::Bleh(std::bind(&Foo::Barry, &f)); }
};
And it doesn't compile (g++ 4.7.3). With error:
test.cpp: In member function ‘void Fooey::Blah()’:
test.cpp:4:1: error: ‘struct Foo Foo::Foo’ is inaccessible
test.cpp:15:23: error: within this context
test.cpp:4:1: error: ‘struct Foo Foo::Foo’ is inaccessible
test.cpp:15:47: error: within this context
However, if I do this:
class Fooey;
void DoStuff(Fooey* pThis);
struct Fooey : public Bar
{
void Blah() { DoStuff(this); }
};
void DoStuff(Fooey* pThis)
{
Foo f;
pThis->Bleh(std::bind(&Foo::Barry, &f));
}
It compiles just fine. What is logic behind this?
Here
struct Fooey : public Bar
{
void Blah() { Foo f; Bar::Bleh(std::bind(&Foo::Barry, &f)); }
};
name lookup for Foo finds the base class of Bar which is inaccesible because Bar inherits privately.
To fix it, qualify the name fully:
void Blah() { ::Foo f; Bar::Bleh(std::bind(&::Foo::Barry, &f)); }
The problem is that, inside Foo or any class derived from it, Foo is the injected class name; a name scoped inside Foo, which hides the same name for the class in the enclosing namespace. In this case, that is inaccessible due to the private inheritance.
You can work around this by explicitly referring to the name in the namespace, in this case ::Foo. Unfortunately, that will break if you move the class into another namespace.
It's a name conflict. For each inherited type, you get a member of that name in your own class. To access the actual type, you need to refer it by its qualified name (in this case, ::Foo).
This feature lets you use shadowed or overridden members of a base class from a derived class:
struct X
{
void Foo();
};
struct Y : public X
{
void Foo()
{
X::Foo(); // calls X's implementation of Foo
}
};
But it does mean that if you mean X as in struct X, you need to qualify it with its full name, calling it ::X.
When you inherit Bar from Foo with private inheritance, you make all of Foo's member data/functions private. So when you inherit Fooey from Bar, it cannot access any of Foo's members.
For more details on private inheritance: http://www.parashift.com/c++-faq/access-rules-with-priv-inherit.html
struct Fooey : public Bar
{
void Blah() { Foo f; Bar::Bleh(std::bind(&::Foo::Barry, &f)); }
};
This block, which contains the scope "fix" also creates another Foo (that is, Fooey already has a Foo object via its inheritance with Bar - this is creating another one and binding its Barry).
What's the difference between these two declarations?
class foo
{
public:
static void bar();
};
and
namespace foo
{
void bar();
}
The way I see it, there is none, since bar in class foo doesn't have access to this, and neither does bar in namespace foo.
This is purely theoretical, of course.
What's the difference between a public static class member function and a global function declared in a namespace?
The class member function will be able to access private static member of the class, while a function inside a namespace will not directly have any kind of data protection
As pointed out by #ValarDohaeris, you can create an object of class foo and call obj.bar() even in an object context, while the same cannot be achieved with namespaces as there are no instances of namespaces
The namespace can be imported via using making bar() a valid call
As mentioned by #John5342 you can use the class foo at template argument. For example in template<typename T> fun() { T::bar(); }
Functions defined at namespace scope can be found via argument dependent lookup:
namespace foo
{
class bar;
void baz (bar);
}
foo::bar x;
baz (x); // Ok, baz is found by ADL
If foo is a class instead of a namespace, this does not work.