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.
Related
Although I've searched, I don't know if this is possible at all.
How can I prevent a library user from writing using namespace myns; anywhere in his/her code?
Let's say I implemented a library that encloses all its elements in a namespace called myns:
namespace myns
{
class MyClass
{
};
class string
{
};
}
This library will be used by another programmer. How can I force him/her to use
// somewhere in code
myns::MyClass myClass;
myns::string myString;
std::string stdString;
instead of
using namespace myns;
// somewhere in code
MyClass myClass;
string myString; // this would most likely be a mess
string stdString;
This would help with namespace collisions.
You can't. The standard says one can write using namespace myns; to get all the names, and there is nothing you can do about that.
If the user gets collisions after using namespace XXX;, that's their own fault. Generally, it is not possible to stop people from shooting themselves in the foot if they try to.
In the end, pulling in all names from some third party namespace is not something that happens on accident, but has been discouraged since about the dawn of time. If the user decides to do it anyways, they better know what they are doing. Really not the problem of the library maintainer.
One (questionable) workaround I can think of is replacing your namespace with a class or a struct of the same name and turning everything in your namespace into a (static) member of this class.
struct myns final
{
class MyClass
{
}
class string
{
}
private:
// private constructor, copy constructor and assignment operator
// ...
};
This would preclude programmers, using your library from writing using namespace myns but... well, like I said, I consider such a workaround to be quite questionable.
Note that users will still be able to use type aliases, such as:
using string = myns::string;
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...
PLEASE READ THE SECOND EDIT FIRST.
I am looking for books or websites that explain in detailed the c/c++ memory management models. One of the things I am trying to understand is:
namespace A {
SomeClass A;
}
vs
namespace A {
static SomeClass A;
}
vs
SomeClass A;
vs
static SomeClass A;
Thank you very much.
EDIT:
Sorry for the confusion, I mixed the concepts together, and asked the wrong questions.
Namespaces allow to group entities like classes, objects and functions under a name. This way the global scope can be divided in "sub-scopes", each one with its own name.
You use keyword using to introduce a name from a namespace into the current declarative region.
For example:
without using namespace you will write:
#include
int main () {
std::cout << "Hello world!\n";
return 0;
}
However you can also write:
#include
using namespace std;
int main () {
cout << "Hello world!\n";
return 0;
}
This allows you not to append napespace identifier before every
In C++ static class has no meaning unlike other OOP languages. You can have static data members methods.
Instead you can create:
1.A static method in class
class SomeClass
{
public: static void myMethod(int x..)
{
}
}
2.Create a free function in namespace
namespace A
{
void myMethod(int x..)
{
}
}
Latter is better suited when you do not need an object. No class no object...
In both cases enclosing a class within namespace allows you to to group entities under a common name.
First, namespaces are only known until compilation, after that they're non-existant. That said, your first half is no different from your second half in the final program, at least as far as I know. Correct me if I'm wrong please.
Then, if both static SomeClass A and SomeClass A are at global scope (file level), then they're the same too.
Next, if both declarations are inside of a class, struct or function, then the static version will be put into the data segment of the executable too, while the non-static variant will be a normal stack variable.
Again, please, correct me if I'm wrong, but that's it as far as I know it.
I keep running into this issue:
class CCreateShortcutTask : public CTask
{
public:
CCreateShortcutTask(
CFilename filename, // shortcut to create (or overwrite)
Toolbox::Windows::CShellLinkInfo definition // shortcut definition
)
...
Having to spell out Toolbox::Windows::CShellLinkInfo seems highly questionable to me. This is in a header, so I surely don't wish to issue a using namespace declaration or I'll drag that namespace into every client file that includes this header.
But I don't seriously want to have to fully name these things in the class interface itself. I'd really love to be able to do something like:
class CCreateShortcutTask : public CTask
{
using namespace Toolbox::Windows;
-or possibly-
using Toolbox::Windows::CShellLinkInfo;
public:
CCreateShortcutTask(
CFilename filename, // shortcut to create (or overwrite)
CShellLinkInfo definition // shortcut definition
)
...
But these seem to be illegal constructs.
Any ideas how to accomplish this?
EDIT: I have asked a broader version of this question here
I think there is a confusion on typedefs.
Using private typedefs is perfectly suitable (and often used). This relies on the fact that in C++ a typedef does not introduce a new type, but a synonym!
namespace VeryLongNamespaceYoullNeverWantToSeeAgain
{
class SuchAStupidNameShouldBeBanned
{
public:
typedef xxx iterator;
typedef zzz value_type;
static std::string Print(value_type);
private:
};
void destroy(SuchAStupidNameShouldBeBanned&);
}
namespace short
{
class MyStruct
{
typedef VeryLongNamespaceYoullNeverWantToSeeAgain::SuchAStupidNameShouldBeBanned Stupid;
public:
void destroyStupid()
{
Stupid::iterator it = m_stupid.begin(), end = m_stupid.end();
std::cout << "Getting rid of ";
for (; it != end; ++it) std::cout << Stupid::Print(*it) << " ";
std::cout << std::endl;
destroy(m_stupid);
}
private:
Stupid m_stupid;
};
}
Thus, private typedefs don't bother:
name lookup: destroy is correctly invoked
use of inner typedefs: iterator is found
use of static methods: Print is found
So you can really use them without many fuss. Furthermore they don't pollute the global space since they are inner to the class and though visible cannot be manipulated by the client directly so he does not rely on them.
Within the source file, you can use namespace aliasing and using directives (not using namespaces please) more liberally, so it's less of an issue.
Maybe namespace alias will help you in some way. You could write the following:
namespace TW = Toolbox::Windows; // define short name
class CCreateShortcutTask : public CTask
{
public:
CCreateShortcutTask(
CFilename filename,
TW::CShellLinkInfo definition
)
Suppose I have
template< unsigned int num >
class SomeFunctionality
{
static unsigned int DoSomething()
{
//...
}
static void DoSomethingElse()
{
}
};
typedef SomeFunctionality<6> SomeFunctionalityFor6;
Semantically, "SomeFunctionalityFor6" is essentially a namespace specific to the template argument, 6. So in the code using this instance of the template instead of doing
int main()
{
SomeFunctionalityFor6::DoSomething();
}
I'd rather have the ability to use a "using" statement ala a real namespace
int main()
{
using SomeFunctionalityFor6;
DoSomething();
}
This, as I would suspect doesn't work. Visual studio complains that it wants a namespace defined by the "namespace" keyword following any using statement.
Is there anyway to do what I'm trying to do? Mainly I just don't want to fully qualify the namespace everytime I call the static methods. I know its mostly just syntactic sugar, but in my opinion it can make code much more readable. I'm wondering if there's even ways to templatize a namespace directly instead of having to use the "class" keyword.
You can't do that. Neither templatized namespace, nor using class_name.
The only places in the code that can use static functions from a class without qualification are derived classes.
In your case, I would use a typedef for some short name, like
int main()
{
typedef SomeFunctionalityFor6 SF6;
SF6::DoSomething();
}
Or you could just create a local object...
int main()
{
SomeFunctionalityFor6 SF6;
SF6.DoSomething();
}
You could replace/change the SF6 object at will.