from the below question i sort of get how enums and namespace scoping works
Scope resolution operator on enums a compiler-specific extension?
However with regard to test code below i'm confused as to why in the below code snippet:
1) i can refer to return type in function signature as test_enum::foo_enum
2) however "using namespace test_enum::foo_enum" is not allowed
namespace test_enum {
enum foo_enum {
INVALID,
VALID
};
}
// Case 1) this is allowed
test_enum::foo_enum getvalue() {
return test_enum::INVALID;
}
//Case 2) is not allowed
using namespace test_enum::foo_enum;
is there a particular reason for not allowing case 2 ?
Also are "enums" more of C style construct and better to avoid in C++ code ?
The reason using namespace test_enum::foo_enum; is not allowed is because foo_enum is not a namespace, it is an enum. What works is using test_enum::foo_enum;
I believe what you are trying to do is something like this:
namespace foo_enum {
enum foo_enum_t {
INVALID,
VALID,
};
}
using foo_enum::foo_enum_t;
This allows you to throw around foo_enum_t freely, but you still have to type out foo_enum::INVALID or foo_enum::VALID
Related
I recently have seen some codes for "using" and then I confused because of I don't know their syntax exactly.
1.
using callable_type = void(__stdcall*)(std::string);
auto Various_native::call_me(callable_type callable)
{
callable("--- from native ---");
}
using ST_CHAR = char;
using namespace System;
In the first two examples "using" plays a role similar to the older "typedef" keyword; it allows you to give a custom name/alias to an existing type, so that in latter code you can use that name (e.g. callable_type) instead of the original name (e.g. void(__stdcall*)(std::string)). That has the advantage of potentially making your code easier to read and/or write, and also the advantage that if you ever decide to change the code to use a different type instead, you only have to modify a single line of code rather than every piece of code that mentions the original type.
The third example (using namespace System;) tells the compiler to automatically look inside the System namespace for identifiers, if no namespace is explicitly specified. So for example if there is a function foo() that was declared inside the System namespace, code after the using namespace System; declaration can simply call foo() rather than having to spell out System::foo() every time.
Have a look at this: https://en.cppreference.com/w/cpp/keyword/using
Here are the ways to use using
/* clasic use: as an improved options to the c keyword typedef
for creating aliases for typenames in the local namespace */
using fullname = std::pair<std::string, std::string>;
using relavently_named_type = std::pair<std::pair<std::string, int>, float>;
fullname name{ "mark", "thompson" };
relavently_named_type variable_name{ { "text", 1 }, 1.0f };
/* importing named symbols to the local namespace */
using std::string, std::array, std::begin, std::end;
array character_array{ 'h','e','l','l','o',' ','w','o','r','l','d', };
string hello_world_string{ begin(character_array), end(character_array) };
std::cout << hello_world_string << '\n';
/* importing all names in a namespace into the local namespace */
using namespace std;
array character_array{ 'h','e','l','l','o',' ','w','o','r','l','d', };
string hello_world_string{ begin(character_array), end(character_array) };
std::cout << hello_world_string << '\n';
/* importing all names from an enum class/struct into the local namespace
(only since c++20) */
enum class material { wood, stone, iron, bronze, glass };
auto without_using = material::wood;
using enum material;
auto with_using = wood;
/* import to other visability from parent class(es) and/or
specify which version of "function" to use when refering to C::function */
class A
{
private:
int function();
};
class B
{
private:
int function();
};
class C : A, B
{
public:
using B::function;
};
Cppreference goes into far more detail but this covers the basic. Your question isn't phrased particulary well but i hope i gave the information you wanted. Generally if you're curios about language features and syntax you can find it on cppreference as long as you know the name. Especially look at their examples.
Or in other words, why allow this to compile?:
#include <iostream>
namespace N{
using namespace std;
string bar() { return "bar";}
void foo() { cout<<"foo\n"<<bar()<<endl; }
}
int main(){
N::foo();
N::cout<<">why allow this??\n"; //Can't ::N:: keep `::std::` to itself?
}
Why not have each namespace resolve its inner include directives internally and only "export" what's actually in that namespace?
Making it work like that would eliminate the need to use fully qualified names inside namespace blocks in most places and I can't think of the drawbacks.
Does this behavior have any purpose besides making things possibly easier on implementers?
Edit:
Turns out it behaves at least somewhat sensible in that there's no contention between a current namespace (B) and an included (using directive'd) namespace (C)—the current namespace (B) always wins. However if the current namespace (B) is included elsewhere (A) then suddenly, the suddenly, B and C start competeting, which must be weird for the user of B who never even knew about C:
#include <iostream>
namespace C {
void method() { std::cout<<"C\n"; }
void cmethod() { std::cout<<"cmethod\n"; }
}
namespace B { using namespace C;
void method() { std::cout<<"B\n"; } }
///^^Library
///>User code
namespace A {
using namespace B;
void aMethod() {
//method(); Error:
//conflict between B::method and C::method even though A doesn't even know about C
B::method(); //Why do I need to write this when I just included B?
cmethod(); //This simply leaks from C because of the u-directive
}
}
int main() { A::aMethod(); }
As far as I can tell, this feature has been explicitly introduced by N0635, proposed by Bjarne Stroustrup himself. The first reason mentioned in that proposal why this feature should be introduced is because he has been "repeatedly asked to make this work:"
namespace A {
int f();
}
using namespace A;
void g()
{
::f(); // call A::f
}
and this
namespace A {
int f();
}
namespace B {
using namespace A;
}
void g()
{
B::f(); // call A::f
}
Under the current rules, this doesn’t work because B::f means "look
for an f declared in B" and f isn’t declared in B.
There are additional reasons mentioned in that paper, though:
One could argue that this interpretation is closer to the way B::f
always worked for a base class B. A benefit would be a
simplification of the library headers because
namespace std {
int printf(const char* ... );
// ...
}
using namespace std;
int main()
{
::printf("Hello pedantic world\n");
}
would now work. It this relaxation is accepted, I would expect the
standard .h headers to be changed to use using-directives (as
originally intended) rather than using-declarations. This would save
hundreds of lines of declarations.
Also, if someone takes
static void f(char);
void f(int);
void g()
{
::f(’a’); // calls f(char)
}
and naively translates it to
namespace { void f(char); }
void f(int);
void g()
{
::f(’a’); // current rules: class f(int)
// relaxed rules: calls f(char)
}
then there would be a change of meaning under the current rules, but
not under my suggested new rules. Some people have worried about the
change of meaning implied by the current rules.
People have responded to this proposal with remarks like "obvius,"
"that was what I always meant," and "I thought that was what it did."
I consider that an indicator that the relaxation will not lead to
added teaching problems, but might reduce such problems.
In fact, namespaces didn't exist in the original version of The C++ Programming Language (1986). They were introduced later, with the aim to manage logical grouping of elements. The ability to compose new namespaces out of other existing namespaces was part of desired features (see section 8.2.8 of the current version of Stroustrup's book).
The standard being as it is, the real question would be: is using the std namespace inside your own one is a good practice in view of Herb Sutter's recommendations ? This would probably be safer:
// === For exposure in a header ====
namespace N{
std::string bar(); // std:: because not sure std is used in the surrounding context
void foo();
}
// === For use in the implemenation ===
using namespace std; // for the implementation
namespace N {
string bar() { return "bar";}
void foo() { cout<<"foo\n"<<bar()<<endl; }
}
The current namespace logic has also advantages. You could for example manage different versions of an library, still allowing for use of legacy parts during a transition period, through explicit scope resoultion.
namespace my_super_lib {
namespace my_super_lib_v1 { // legacy API
void super_f() { std::cout<<"1"; }
void super_old() {} // obsolete,
}
namespace my_super_lib_v2 { // new API
void super_f(int a) { std::cout<<"2"; }
}
using namespace my_super_lib_v2; // use now the new API
using my_super_lib_v1::super_old; // but still allow some legacy
};
Stroutrup's FAQ shows similar examples with in addition a clear case for inline namespaces.
Well, if you don't want that to happen, don't do using namespace std or similar inside the namespace N...
It is actually quite useful sometimes to be able to "export" something from one namespace into another. Imagine that I've got this clever set of functions to do flubbetiflap functionality. To this goal, I'm borrowing a set of functions in the kerflunk namespace, which provides some really useful type declarations I want to use in my functionality. So I can do:
namespace flubbetiflap
{
using namespace kerflunk;
... all the good code what I wrote to do flubbetiflap goes here ...
};
Now, the users of my flubbetiflap won't actually need to know that I'm using kerflunk for my implementation.
Sure, there could be all sorts of atlernative solutions that one COULD come up with for doing this. But I can certainly see how it can be useful.
Obviously, nobody outside of the C++ committee would actually know much about the discussion that went on to determine how this should work...
Suppose, if I have a namespace in one header file. I don't want that people should be able to expand it to other files. Is it possible in C++ ?
//N.h
namespace N {
//...
}
//Other.h
#include"N.h"
namespace N { // <--- don't allow this
void foo () {}
}
[Note: Asking this for knowledge and curiosity. Because, have heard many times that one should not expand std.]
AFAIK, you can't do this in C++, and I don't see any practical reason for it either.
You can wrap your code into a class instead of a namespace; since a class declaration cannot be spread over several headers, others cannot add to it.
But again, I don't see why you think this is a problem, and I'd be curious to see an example.
You can only ask people to behave, not force them. Perhaps you can try this:
namespace milind
{
namespace Private
{
// Please don't add stuff to my private namespace
... Important implementation details goes here
}
}
You could use a class with all statics instead of a namespace to simulate the behavior.
Found one way. I can encapsulate the namespace inside another dummy type of namespace and then use it. To avoid verbosity, we can use an alias to the existing namespace.
i.e.
//N.h
namespace DUMMY_ { // <--- put a dummy outer namespace
namespace N {
//...
}
}
namespace N = DUMMY_::N; // alias the name to the original name
//Other.h
#include"N.h"
namespace N { // <--- error !!
void foo () {}
}
Edit: With above solution it's less likely that people would expand namespace N. However, as #Charles comment, still DUMMY_ is visible to the reader. Which means one can still do like:
namespace DUMMY_ {
namespace N { // ok
void foo () {}
}
}
So only way remains to prohibit the undesired expansion is by replacing:
namespace N = DUMMY_::N;
with,
#define N DUMMY_::N
This will work as per expected; but we enter the region of macros.
Would you recommand prefixing global namespaces with ::? (for instance ::std::cout instead of std::cout) Why? Is it faster to parse for the C++ compiler?
Thanks.
Only do this to disambiguate.
I have a piece of code where this is necessary since I’m in a namespace X which has a function for a standard deviation – std. Whenever I want to access the std namespace, I need to use ::std because otherwise the compiler will think that I am referring to said function.
Concrete example:
namespace X {
double std(::std::vector<double> const& values) { … }
void foo(::std::vector<double> const& values) {
::std::cout << std(values) << ::std::endl;
}
}
It has nothing to do with parsing speed. C++ uses Argument-dependent name lookup - Koenig Lookup and when you have to make sure that the compiler uses the symbol from the global root namespace you prefix it with ::. If you don't the compiler might also use function definitions from other namespaces when it sees fit (depending on the lookup method).
So, it is better not to do it unless you have to.
You don't need to, as the compiler will
a) find it anyway
b) output an error if there are any ambiguations, like
namespace foo
{
int test()
{
return 42;
}
}
namespace bar
{
namespace foo
{
int test()
{
return 42;
}
}
}
int main()
{
using namespace bar;
return foo::test(); // error, could be ::foo::test or ::bar::foo::test
}
Don't do that. It clutters your code and disables the option to implement a self-made variant of the functions you are using.
I cannot see any good reason to do this. It makes the code less readable, and should only be used when you explicitly must tell the compiler to use the root namespace. Like when there is ambiguities.
How can I get rid of the warning, without explicitly scoping the enum properly? The standards-compliant code would be to compare against foo::bar::mUpload (see here), but the explicit scopes are really long and make the darn thing unreadable.
maybe there's another way that doesn't use typedef? i don't want to modify the enum--i didn't write it and its in use elsewhere.
warning C4482: nonstandard extension used: enum 'foo::bar::baz' used in qualified name
namespace foo {
class bar {
enum baz {mUpload = 0, mDownload};
}
}
typedef foo::bar::baz mode_t;
mode_t mode = getMode();
if (mode == mode_t::mUpload) //C4482
{
return uploadthingy();
}
else
{
assert(mode == mode_t::mDownload); //C4482
return downloadthingy();
}
If the enum is defined within a class, the best that you can do is bring the class into your own scope and just use class_name::value or define a typedef of the class. In C++03 the values of an enum are part of the enclosing scope (which in your case is the class). In C++0x/11 you will be able to qualify the values with the enum name:
namespace first { namespace second {
struct enclosing {
enum the_enum { one_value, another };
}
}}
using first::second::enclosing;
typedef first::second::enclosing the_enclosing;
assert( enclosing::one_value != the_enclosing::another );
In the future, your usage will be correct (C++11):
typedef first::second::enclosing::the_enum my_enum;
assert( my_enum::one_value != my_enum::another );
You can enclose your enum into a namespace, and then use a using statement on that namespace.
This obviously only works for enum's outside of class scope.
In your case I don't see why don't you refer to it as bar::mUpload (after using namespace foo, or using foo::bar)
You can use a typedef for foo::bar:
typedef foo::bar fb;
//...
fb::baz m = fb::mUpload;
Or are you looking for something different?