Is it possible to put a function declaration within an unnamed namespace? - c++

I have a file with a set of functions. For one of the functions, I want to write a helper function which basically takes a char * and skips all whitespaces.
Here's how I thought it should be done:
namespace {
const int kNotFound = -1;
void SkipWhitespace(const char *s); // forward declaration - doesn't seem to work?
}
void foo(const char *s1, const char *s2) {
// do some stuff
SkipWhitespace(s1);
SkipWhitespace(s2);
// continue with other stuff
}
void SkipWhitespace(const char *s) {
for (; !isspace(s); ++s) {}
}
But this gives me a compiler error. Do I need to put the definition within the unnamed namespace?

You have to define it in the anonymous namespace as well:
namespace {
...
void SkipWhitespace(const char *s); // forward declaration - doesn't seem to work?
}
void foo(const char *s1, const char *s2) {
...
}
namespace {
void SkipWhitespace(const char s*) {
for (; !isspace(s); ++s) {}
}
}
But unless there is a cyclic dependency, I'm not sure what the value of this is. Just declare and define the function in one go.

An unnamed namespace behaves as if it was replaced with a namespace with a uniquely generated name immediately followed by a using directive.
This means that your function declaration belongs to a namespace exactly as if the namespace actually had a name. As such, its definition should live in the same namespace : either simultaneously declare and define the function, or add an enclosing namespace {} around the definition (which works because all occurrences of the unnamed namespace in a translation unit refer to the same namespace).
namespace {
void SkipWhitespace(const char s*) {
for (; !isspace(s); ++s) {}
}
}

You probably need to see this topic as well:
Superiority of unnamed namespace over static?
BTW, why this function:
void SkipWhitespace(const char *s);
Why not this:
void SkipWhitespace(std::string &s);
??

Related

Is a fully qualified class name down to global scope ever required for out-of-line member function definitions?

This question got me wondering whether it is ever useful/necessary to fully qualify class names (including the global scope operator) in an out-of-class member function definition.
On the one hand, I've never seen this done before (and the syntax to properly do so seems obscure). On the other, C++ name lookup is very non-trivial, so maybe a corner case exists.
Question:
Is there ever a case where introducing an out-of-class member function definition by
ReturnType (::Fully::Qualified::Class::Name::MemberFunctionName)(...) { ... }
would differ from
ReturnType Fully::Qualified::Class::Name::MemberFunctionName(...) { ... } (no global scope :: prefix)?
Note that member function definitions must be put into a namespace enclosing the class, so this is not a valid example.
A using-directive can cause Fully to be ambiguous without qualification.
namespace Foo {
struct X {
};
}
using namespace Foo;
struct X {
void c();
};
void X::c() { } // ambiguous
void ::X::c() { } // OK
It's necessary if one is a masochist and enjoys writing stuff like this
namespace foo {
namespace foo {
struct bar {
void baz();
};
}
struct bar {
void baz();
};
void foo::bar::baz() {
}
void (::foo::bar::baz)() {
}
}
One can of course write the second overload as foo::foo::bar::baz in global scope, but the question was whether or not the two declarations can have a different meaning. I wouldn't recommend writing such code.
If a using directive is used then there can be a confusing code.
Consider the following demonstrative program
#include <iostream>
#include <string>
namespace N1
{
struct A
{
void f() const;
};
}
using namespace N1;
void A::f() const { std::cout << "N1::f()\n"; }
struct A
{
void f() const;
};
void ::A::f() const { std::cout << "::f()\n"; }
int main()
{
N1::A().f();
::A().f();
return 0;
}
So for readability this qualified name
void ::A::f() const { std::cout << "::f()\n"; }
shows precisely where the function is declared.

How to access function defined in namespace in other .cc file

I have a file named test.cc
#include <stdio.h>
int doit(){
return 4;
}
namespace abc {
int returnIt(int a){
return a;
}
}
I can use doit(), but how can I use this function in namespace in my main.cc without using .h file:
using namespace abc;
int doit();
int main(int argc, const char * argv[]) {
cout<<returnIt(3)<<endl; // print 3
cout<<doit(); // print 4
return 0;
}
You can call functions by first declaring them. Example:
namespace abc {
int returnIt(int a); // function declaration
}
int main() {
abc::returnIt(3); // the declared function can now be called
Note that the declaration must be exactly the same as used elsewhere in the program. To achieve identical declarations across translation units, it is conventional to put the declaration into a separate file (called a header) and include that file using the pre-processor whenever the declaration is needed.
All you need is to simply write the functions before the main function. That way, the compiler has processed the function prototypes by the time it encounters them in main and can validate the function call.
int doit()
{
return 4;
}
int returnIt(int a)
{
return a;
}
int main(int argc, const char * argv[])
{
cout<<returnIt(3)<<endl; // print 3
cout<<doit(); // print 4
return 0;
}
In general, avoid using namespace;. It makes for code that can be broken or be rendered less readable due to incorrect variable/function usage. That is because too many symbols can occupy the same (global) scope.
If another library needs to used, as user4581301 pointed out, then it may be simpler to use eerorika answer/method.

expected primary-expression before 'unsigned' in my program (destructors and constructors problems)

Hi I am new in c++ and I make skeleton of program and I have some problems with destructors and constructors.
My head.cpp:
#include <iostream>
#include "set_char.hpp"
using namespace std;
int main()
{
set_char *z1 = new set_char(unsigned char *zbior[]);
delete z1;
return 0;
};
My set_char.hpp class file:
#define ROZMIAR_MAX 256
class set_char
{
unsigned char zbior[ROZMIAR_MAX];
public:
set_char(unsigned char *zbior[]);
~set_char(unsigned char *zbior[]);
int nalezy(unsigned char);
int licznosc();
void dodaj(unsigned char);
void usun(unsigned char);
};
And my set_char.cpp file:
#include "set_char.hpp"
#include <iostream>
#include <math.h>
using namespace std;
set_char(unsigned char *zbior[]);
~set_char(unsigned char *zbior[]);
void set_char::dodaj(unsigned char)
{
};
void set_char::usun(unsigned char)
{
};
int set_char::nalezy(unsigned char)
{
};
int set_char::licznosc()
{
};
Among others:
you should not add any parameters in destructors:
~set_char(unsigned char *zbior[]);
^^^^^^^^^^^^^^^^^^^^^^ --- remove it
When creating set_char you should provide pointer to your array, and not the actual parameter type:
set_char *z1 = new set_char(unsigned char *zbior[]);
^^^^^^^^^^^^^^^^^^^^^^
1
You did not define your Constructor and Destructor
You declared them both in your set_char.hpp
set_char(unsigned char *zbior[]);
~set_char(unsigned char *zbior[]);
However in set_char.cpp you re-declare them again without a return type. Defining a Constructor and Destructor outside of a class is illegal. Your compiler thinks they are functions and searches for a return type.
2
a Destructor may not have any arguments.
3
If you define an array as an argument in a Function or a Constructor or Destructor with brackets '[]', it may not be of variable length, thus it must be defined. If it is intended to be of variable length, it must be left out.
4
You are calling the constructor in a bad way using:
new set_char(unsigned char *zbior[]);
You already declared what arguments it takes, so hand it the arguments. A null pointer, for example.
The correct way to do it in set_char.hpp:
set_char(unsigned char *);
~set_char();
The correct way to do it in set_char.cpp:
set_char::set_char(unsigned char *zbior)
{
//Your definition
}
set_char::~set_char();
{
//Your definition
}
The correct way to do it in head.cpp:
set_char *z1 = new set_char(0x0);
Also side-note, usually using the define macro to define constants, is a C way. In C++ it is usually done with:
static const size_t ROZMIAR_MAX 256;
Second side-note. It is considered 'neater' code if you have your constants/functions and whatnot defined inside a namespace

Returning array of character error in c++?

I have these two files table.cpp and table.h in my program code apart from the main.cpp. The files are described as below
table.cpp
#include <iostream>
#include "table.h"
using namespace std;
// accessor function for Name
char* PeriodicTable::Name()
{
return Name;
}
// accessor function for Symbol
char* PeriodicTable::Symbol()
{
return Symbol;
}
table.h
#ifndef TABLE_H
#define TABLE_H
class PeriodicTable
{
char Name[15], Symbol[3], GroupName[20], Block, State[25], Colour[15], Classification[20];
int GroupNo, AtomicNo, PeriodNo;
float Weight;
public:
char* Name();
char* Symbol();
};
#endif
but the problem is that the IntelliSense(since I am using Visual C++ Express 2010) shows a red curved underline below the name and symbol in the accessor function in table.cpp. I can't understand why???
Your member functions and member variables have the same name. This is not possible in C++. That's why various conventions exist for naming member variables, e.g. m_name, name_ etc. (NB: When dealing with underscores in identifiers make sure you don't use a reserved name by accident.)
You might wonder why and how that could possibly go wrong. In your example there clearly is no way to invoke operator() on char[15], but the problem is that the compiler only knows that after performing semantic analysis. There could also be cases where it is impossible to disambiguate. For example:
struct Func {
void operator()() { };
};
struct C {
Func f;
void f() {}
};
int main() {
C c;
c.f(); // which one?
}

Anonymous Namespace Ambiguity

Consider the following snippet:
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
int main()
{
Foo(); // Ambiguous.
::Foo(); // Calls the Foo in the global namespace (Foo #1).
// I'm trying to call the `Foo` that's defined in the anonymous namespace (Foo #2).
}
How can I refer to something inside an anonymous namespace in this case?
You can't. The standard contains the following section (§7.3.1.1, C++03):
An unnamed-namespace-definition behaves as if it were replaced by
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where all occurrences of unique in a
translation unit are replaced by the
same identifier and this identifier
differs from all other identifiers in the entire program.
Thus you have no way to refer to that unique name.
You could however technically use something like the following instead:
int i;
namespace helper {
namespace {
int i;
int j;
}
}
using namespace helper;
void f() {
j++; // works
i++; // still ambigous
::i++; // access to global namespace
helper::i++; // access to unnamed namespace
}
While Georg gives standard-complient, correct, right, and respectable answer, I'd like to offer my hacky one - use another namespace within the anonymous namespace:
#include <iostream>
using namespace std;
namespace
{
namespace inner
{
int cout = 42;
}
}
int main()
{
cout << inner::cout << endl;
return 0;
}
The only solution I can think of that doesn't modify the existing namespace arrangement is to delegate main to a function in the anonymous namespace. (main itself is required to be a global function (§3.6.1/1), so it cannot be in an anonymous namespace.)
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
namespace { // re-open same anonymous namespace
int do_main()
{
Foo(); // Calls local, anonymous namespace (Foo #2).
::Foo(); // Calls the Foo in the global namespace (Foo #1).
return 0; // return not optional
}
}
int main() {
return do_main();
}
The only real way is to put the code you want to access that namespace within the namespace itself. There's no way to resolve to the unnamed namespace otherwise, since it has no identifier you can give it to solve the ambiguous resolution problem.
If your code is inside the namespace{} block itself, the local name gets priority over the global one, so a Foo() will call the Foo() within your namespace, and a ::Foo() will call the namespace at global scope.
Just rename the local namespace function.