In a .cpp file, an anonymous namespace basically has file-wide linkage (after #includes) because the .cpp file will never be included by another file. But, the same pattern in a header file propagates that anonymous namespace to wherever it is included in. Is there a way to create a similar effect in a header file? I ask because template implementations must be in headers.
A simple example in a regular .h file would be this:
// object.h
namespace {
using verbose::namespace::type;
}
...
struct object {
type value;
}
or similarly in some template implementation file. The type type would be in-scope of wherever this file is included.
Is there a way around this?
EDIT: I think I found a verbose but workable answer.
// object.h
struct Namespace {
using verbose::namespace::type;
Namespace() = delete;
struct object {
type value;
};
};
using Namespace::object;
This should do the trick:
// object.h
{
namespace {
using verbose::namespace::type;
}
...
struct object {
type value;
}
}
Namespaces should only be valid within the code block they're defined in.
Related
Let's say I have two files
Something.thrift
namespace cpp something
struct Something { ... }
Marvelous.thrift
include "Something.thrift"
namespace cpp marvelous
struct IncludingSomething {
1: required something::Something;
}
Here the scope resolution operator is not recognized, how do I access Something from Marvelous.thrift?
Using the dot operator. So like this
include "Something.thrift"
namespace cpp marvelous
struct IncludingSomething {
1: required something.Something;
}
I've got two questions.
Question 1: Can someone provide an example of how to define/redefine a variable in a namespace. I've provided my own guess for you to base an your answer from.
// namespace.hpp
namespace example
{
static string version;
static int x;
}
And then in a .cpp how do I redefine those variables?
// namespace.cpp
namespace example
{
version = "0.1"; // ?????
x = 0; //???
}
Question 2: How would I attach a permanent class object onto a namespace from the same .hpp file? Something like this:
// namespace.hpp
class Idk
{
public:
int doThis();
}
namespace example
{
Idk idkObject;
}
The code above, when included multiple times (from different files) will replace the object, which will cause compilation errors. Once again, I need a permanent way to attach a object to a namespace its header file.
Instead of 'static', write 'extern' in the header file and include the data type in the variable definitions in the cpp file.
Question 1: You need to specify the type also
// namespace.cpp
namespace example
{
string version = "0.1"; // ?????
int x = 0; //???
}
Question 2: You shouldn't create a 'non-static' object in a header file irrespective of the namespace. You should just use static here also or else you should use extern in header file and define the variable inside a cpp file. {Note it's a little different with templatized classes}
// namespace.hpp
class Idk
{
public:
int doThis();
}
namespace example
{
static Idk idkObject;
}
// namespace.cpp
namespace example
{
Idk idkObject; // Default constructor
}
I am facing a problem when implementing some new code to an existing library. This library already references a class with a name say 'foo'. The same name is used as a namespace in the other header file which has to be included to implement the new functionality. Since both the header files are a part of legacy code libraries I cannot amend them. So here I am looking for any way so as to avoid the Compiler Error (C2757: a symbol with this name already exists and therefore this name cannot be used as a namespace name). I am not sure whether it is possible or not. Hence, Any help shall be appreciated. Thanks
For clarity here is the sample code illustration for the issue:
HeaderA.h
class foo
{}
HeaderB.h
namespace foo
{
class ABC{}
}
HeaderC.h
#include <HeaderA.h>
#include <HeaderB.h>
using namespace foo;
class Toimplement{
ABC a; //Throws Error C2757
}
You can try the following workaround:
namespace bar {
#include "HeaderA.h"
}
#include "HeaderB.h"
...
bar::foo fooObject;
foo::ABC abcObject;
Include one of header file in new namespace.
namespace headerb {
#include <HeaderB.h>
}
...
...
headerb::ABC a1;
ABC b2;
In your example, the simplest approach is to not include HeaderA.h in HeaderC.h. The class foo isn't needed in Toimplement.
so let's assume you need the visibility of both files, and you want to link to the symbols included by HeaderA:
// header a
class FOO {};
// followed by a file with your declarations/disambiguators
typedef FOO wwlib_FOO;
// header b
namespace FOO {class ABC {};}
// followed by a file with your declarations/disambiguators
namespace vvlib_FOO = FOO;
// and finally usage
using namespace FOO; // note: using `using` is a good way to introduce complications like this one
void fn() {
class FOO t;
wwlib_FOO t2(t);
vvlib_FOO::ABC abc;
...
the namespace trick won't work, apart from very very simple cases (unless it's entirely templates or inlines, which is very unusual). you'll just end up with duplicated code, classes that you can't pass around, and missing references at link-time.
I want to make a namespace that will contain several classes as part of a "package".
Do I have to declare all of the classes within the namespace?
For example, if I have a "2dEngine.h" which defines the 2dEngine namespace, do I have to declare all of the individual classes within that header file? Or can I still separate them into separate header (.h) files and have them be part of the namespace?
Pseudo example:
TwoEngine.h
namespace TwoEngine
{
class Canvas
{
// Define all of Canvas here
};
class Primitive
{
// Define all of Primitive here
};
}
Instead of doing that, I want to have Canvas and Primitive be their own .h files and just somehow state that they are part of that namespace.
Sorry, I'm still pretty new to this.
Yes, you can split the namespace into multiple blocks (and hence files). Your classes will belong to the same namespace as long as they are declared in the namespace block with the same name.
// Canvas.h
namespace TwoEngine
{
class Canvas
{
// Define all of Canvas here
};
}
// Primitive.h
namespace TwoEngine
{
class Primitive
{
// Define all of Primitive here
};
}
Namespaces can be discontiguous. You can take advantage of this by keeping relevant classes in your 2DEngine.h which probably is going to be used by client code and will be shipped as part of your library.
Anything else, that is not to be revealed to the outside world can still be put in the same namespace but in a separate header file (which is not shipped).
Header H1.h (part of the library interface to the external world)
namespace TwoEngine
{
class Canvas
{
// Define all of Canvas here
};
}
Header H2.h (not part of the library interface to the external world)
#include "H1.h"
namespace TwoEngine // reopen the namespace and extend it
{
class Primitive
{
// Define all of Primitive here
};
}
Yes just use the name space directive inside the implementation files also.
I have this definition of the function in my class.
The .hpp file:
class SomeClass
{
public:
static string DoStuff(string s);
};
The .cpp file:
#include "header.hpp"
string SomeClass::DoStuff(string s)
{
// do something
}
Compiler says:
**error C2039: 'DoStuff' : is not a member of 'SomeClass'**
Can somebody help?
EDIT:
actual offending code
header definition
class DDateTime{
public:
static string date2OracleDate(DATE Date);
}
string DDateTime::date2OracleDate(DATE Date)
{
string s;
s="TO_DATE('" + DDateTime::DateFormat("%d/%m/%Y",Date) + "','dd/MM/YYYY')";
return s;
}
Usually, .cpp files must include the matching .h or .hpp file.
Is it the case here ?
You can also have namespace issue (missing namespace in .cpp file or static method definition outside of the namespace, and so on.).
Actually, it is difficult to answer until we have the real breaking code.
Moreover, I don't know if this is sample code, but it seems you used something like using std::string or using namespace std in your header file.
This is a bad idea because it will polute every file in which your header is included. What If someone wants to use your header file but don't want to "use" std because string is the name of one of its classes ?
Have you included the header file in your cpp file?
Maybe a namespace issue? You could have a SomeNamespace::SomeClass with a static member function and a ::SomeClass in the outer namespace without the static member function.
Are you missing
#include<string>
in your header file?
Are you trying to call DoStuff from a double pointer to your instance? Example:
SomeClass **class;
class->DoStuff();
If so do this:
SomeClass **class;
(*class)->DoStuf();