How to access variables across namespaces in thrift - c++

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;
}

Related

Anonymous namespace in template implementation file

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.

Creating a C++ namespace in header and source (cpp)

Is there any difference between wrapping both header and cpp file contents in a namespace or wrapping just the header contents and then doing using namespace in the cpp file?
By difference I mean any sort performance penalty or slightly different semantics that can cause problems or anything I need to be aware of.
Example:
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
namespace X
{
void Foo::TheFunc()
{
return;
}
}
VS
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
using namespace X;
{
void Foo::TheFunc()
{
return;
}
}
If there is no difference what is the preferred form and why?
The difference in "namespace X" to "using namespace X" is in the first one any new declarations will be under the name space while in the second one it won't.
In your example there are no new declaration - so no difference hence no preferred way.
Namespace is just a way to mangle function signature so that they will not conflict. Some prefer the first way and other prefer the second version. Both versions do not have any effect on compile time performance. Note that namespaces are just a compile time entity.
The only problem that arises with using namespace is when we have same nested namespace names (i.e) X::X::Foo. Doing that creates more confusion with or without using keyword.
There's no performance penalties, since the resulting could would be the same, but putting your Foo into namespace implicitly introduces ambiguity in case you have Foos in different namespaces. You can get your code fubar, indeed. I'd recommend avoiding using using for this purpose.
And you have a stray { after using namespace ;-)
If you're attempting to use variables from one to the other, then I'd recommend externalizing them, then initializing them in the source file like so:
// [.hh]
namespace example
{
extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
int a, b, c;
}
// Then in the function below, you can init them as what you want:
void reference
{
example::a = 0;
}
If the second one compiles as well, there should be no differences. Namespaces are processed in compile-time and should not affect the runtime actions.
But for design issues, second is horrible. Even if it compiles (not sure), it makes no sense at all.
The Foo::TheFunc() is not in the correct namespacein the VS-case. Use 'void X::Foo::TheFunc() {}' to implement the function in the correct namespace (X).
In case if you do wrap only the .h content you have to write using namespace ... in cpp file otherwise you every time working on the valid namespace. Normally you wrap both .cpp and .h files otherwise you are in risk to use objects from another namespace which may generate a lot of problems.
I think right thing to do here is to use namespace for scoping.
namespace catagory
{
enum status
{
none,
active,
paused
}
};
void func()
{
catagory::status status;
status = category::active;
}
Or you can do the following:
// asdf.h
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
Then
// asdf.cpp
#include "asdf.h"
void X::Foo::TheFunc()
{
return;
}

What is the difference between "using" namespace and declaring namespace?

Could somebody tell me what is the difference between
using namespace android;
....
and
namespace android {
....
}
I found that almost all .cpp files in Android source code use the second one.
Also, If I want to include some files that use the type of second one in my own project, do I need to use namespace android{...} too?
Because if I do not, compiler would report error when I call methods of included files. Or do I need to add any prefix before method call?
namespace android {
extern int i; // declare here but define somewhere
void foo ();
}
-- is used for scoping variables and functions inside a particular name. While using/calling those variables/functions, use scope resolution operator ::. e.g.
int main ()
{
android::foo();
}
There is no restriction for putting all namespace declarations in a single body instance. Multiple namespace android bodies spread across several files, is possible and also recommended sometimes. e.g.
// x.cpp
namespace android {
void somefunc_1 ();
}
// y.cpp
namespace android {
void somefunc_2 ();
}
Now, sometimes you may find using :: operator inconvenient if used frequently, which makes the names unnecessarily longer. At that time using namespace directive can be used.
This using directive can be used in function scope / namespace scope / global scope; But not allowed in class scope: Why "using namespace X;" is not allowed inside class/struct level?).
int main ()
{
using namespace android;
foo(); // ok
}
void bar ()
{
foo(); // error! 'foo' is not visible; must access as 'android::foo()'
}
BTW, Had using namespace android; declared globally (i.e. above main()), then foo() can be accessed without :: in Bar() also.
My answer is probably only helpful if you are more experienced with Java. I'm guessing since you are doing android stuff that this is the case.
The following means that you are declaring a class called MyClass in the namespace android. The qualified name of the class would be android::MyClass.
namespace android {
class MyClass {...};
}
It can be thought of similarly to the Java code:
package android;
public class MyClass {...}
The following means that you can use classes, functions etc. defined in the android namespace without having to use their qualified name (assuming they have been included).
using namespace android;
This
#include <path/to/MyClass.h>
using namespace android;
can be thought of similarly to the Java code:
import android.MyClass;

C++ namespace alias in entire class scope

I expected to be able to use a namespace alias in a class declaration but get a compiler syntax error.
struct MyClass
{
namespace abc = a_big_namespace;
void fn() {
abc::test();
}
};
The only way I can get it to work is to put the alias in every function.
void fn() {
namespace abc = a_big_namespace;
abc::test();
}
Additionally I would like to be able to use the alias for function parameters. I haven't found a work-around for that.
void fn(abc::testType tt) {
abc::test(tt);
}
Is there a way to do what I want?
EDIT: my solution
I found that I didn't need unnamed namespace for my particular problem and can simply do this:
namespace myspace
{
namespace abc = a_big_namespace;
struct MyClass
{
void fn(abc::testType tt) {
abc::test(tt);
}
};
}
To switch to the other library, which is what my alias namespace refers to I just change the alias. This method even allows me to have the same class in a single file twice, each time refering to a different library.
Thanks for all your help.
Namespace alias in the class definition is illegal, as specified by the language specification.
Its allowed in only in namespace scope or function scope.
You can make alias at namespace scope. But that will be make permanent alias which can be used from other files as well. But the solution is simple : you can use unnamed namespace to prevent alias (and therefore all symbols from the big namespace) from being visible from other files. This is how it can be done:
//MyFile.cpp
namespace myspace
{
namespace //this is unnamed namespace
{
namespace abc = a_big_namespace;
}
struct MyClass
{
void fn()
{
abc::test(); //don't worry, this will work!
}
};
}
//OtherFile.cpp
myspace::abc::test(); //error - that means, prevention worked.
The alias is not visible from other files. When compiling OtherFile.cpp, GCC (4.5.0) says,
'myspace::abc' has not been declared
That proves the alias abc is visible only in MyFile.cpp. Thanks to unnamed namespace.
Demo : http://www.ideone.com/2zyNI (though it doesn't demonstrate OtherFile concept. I cannot have more than one file at ideone.com)
The scope of a namespace alias is a code block.
So you can put it in any code block.
BUT, you can't put it inside a class, because that will mean it's a member of the class.
A namespace alias can't be a member.
More about namespace aliases:
What is the scope of a namespace alias in C++?
Namespaces
It works if you declare the alias outside of the struct.
You can of course also put the alias outside the class:
namespace abc = a_big_namespace;
struct MyClass {
void fn()
{ abc::test(); }
};

Is it possible to avoid C++ compiler error (C2757) where 2 different header files contain same symbol for namespace & class?

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.