how to limit scope of literal operators - c++

Is there a possibility to limit the scope of literal operators?
I would like to define some postfixes to make some things easier to specify, but this only has relevance to things directly connected to the specific class or the their child classes. Name spaces of other code that uses this classes should not be affected by this.

Use a namespace. wandbox example
namespace my_lits
{
int operator ""_aaa(const unsigned long long x)
{
return x + 1;
}
}
int main()
{
{
using namespace my_lits;
std::cout << 100_aaa << "\n";
}
{
// Will not compile!!!
std::cout << 100_aaa << "\n";
}
}
Is there a way to make this namespace always visible then in class' scope?
It is not possible to bring a namespace into scope inside a class. Refer to this question and this other one for more details.
Furthermore, UDLs cannot be declared in class scope.

Related

What does using ::fun mean when fun is a function?

void fun(){
std::cout << "hello" << std::endl;
}
namespace enc{
using ::fun;
}
This code above gives no error. I want to understand what's going on here.
What does using ::fun; mean?
Breaking this down we have:
void fun() is a function that does not return a value (essentially nothing).
:: is a scope resolution operator. For example, cout and cin are defined in the std namespace. To qualify their names without using the using declaration we have to qualify them with std::cout and std::cin
To answer the main question, however:
using ::fun; is called a using declaration. A using declaration means that you can introduces namespace members into other namespaces, etc. This means that fun will now be visible as ::enc::fun;
For example:
void fun() {
std::cout << "hello" << std::endl;
}
namespace enc {
using ::fun;
}
void Reallyfun()
{
enc::fun(); // Which calls ::fun
}
using a synonymous declaration introduces a name from one declarative region into another. In this case, the name fun is introduced into the namespace ::enc and it is synonymous with ::fun.

Specifying class variables vs. method variables C++

Here's an extremely basic example of my question.
#include <iostream>
#include <string>
using namespace std;
int x;
void test(int x) {
x += 3;
cout << x << endl;
}
int main() {
test(x);
cout << x << endl;
return 0;
}
the output is:
"3" (new line) "0"
How can I specify inside of the "test()" function that I want the class's 'x' variable to have the 3 added to it instead of the temp variable inside of the function?
In java you specify that you're dealing with the function/method's variable by using '"this". Is there a similar way to do this in C++?
In your case you can use :: to specify to use global variable,
instead of local one:
void test(int x) {
::x += 3;
cout << ::x << endl;
}
And it is not class member or so on just global and local.
In the C++ language, create a class or struct and you can use this->x the same as this.x in the Java language.
First of all, thank you for stating that you come from Java. This will help us a lot in terms of helping you!
Now, let's analyze your code
#include <iostream>
#include <string>
using namespace std;
Including some headers, using the std namespace (not recommended, BTW), everything's okay here.
int x;
You declare a variable named x of type int at global scope, with an initial value of zero (this only applies to objects at global scope!).
void test(int x) {
x += 3;
cout << x << endl;
}
You declare a function test that takes a parameter x of type int and returns void (a.k.a: nothing). The function increments the value of its intenral x variable by 3, then prints that to standard output by means of std::cout. Just to be clear, once you declare the int x parameter, it "hides" the int x at global scope, thus if you want to access the later, you have to use another way (see below).
int main() {
test(x);
cout << x << endl;
return 0;
}
You declare the special main function, taking no parameters and returning int. The function calls test with the global int x as argument, then prints the value of the global x to the standard output by means of std::cout, and finally returns zero, indicating successful execution.
Now, you have a big misconception, that you can attribute to the single-paradigm design of the Java language. In Java, there's no concept of "global functions", not to even say there are no "functions" at all. You only have "classes" with "methods".
In C++, this is not the case. The C++ language is a multi-paradigm one; it allows you to do imperative programming, structured programming, object-oriented programming, and even functional programming (you're not expected to have understood that last sentence completely)! When you declare anything without specifying an scope, it's said to lie in the global scope. The global scope can be accessed by anything, anywhere. In the example you presented there are no classes involved!
In the global scope, something like void test(int) is not a method, but a function. There's no class "owning" that function; let's say it's of "everyone" ;). A function is just a block of code that you can reuse by giving it arguments, if the function has them at all. In C++, you use classes to encapsulate data and corresponding code in a single "packed" black-box entity, not for, well, anything, like in Java.
Now, (this is somewhat like Java, but be careful!), when you pass a "plain" object, such as an int or something more funky and complex like std:: (you were not expected to understand that...) to a function, that function gets a copy of that object. The int x in test is not the same as the one main passed to it. If you assign to it inside test, you'll notice main "sees no difference". In Java, this applies too, but only to the fundamental types like int, but in C++ it does for all types.
If you want to be able to change the variable you got, just use references. You get a reference of any type T by typing T&. So, if you assign to a int& x inside the now modified test, main will "see" all changes.
Finally, there's the :: operator. It's used to access stuff in some scope from, well, other scopes. It has the form namespace-or-class::stuff. So for example, std::cout refers to identifier cout in namespace std. There's a special case: if the left operand is not given, :: accesses the global scope. This is useful whenever you "hide" something from the global scope. So, for example, in test, you could say ::x, and that would refer to the x in the global scope!
void test(int x) {
// ...
::x += 123;
}
Edit: If you're curious, you can take a glance at how classes in C++ work with this (I won't explain it, because that's off-topic)...
#include <iostream>
int x = 0;
class MyClass {
private:
int x;
public:
MyClass() : x(0) {}
void test(int x) {
this->report(x);
std::cout << "Doing some magic...\n";
this->x += x;
this->report(x);
}
void report(int x) {
std::cout << "this->x = " << this->x << '\n';
std::cout << "x = " << x << '\n';
}
};
int main() {
MyClass c;
c.report();
x += 123;
c.test(x);
x += 456;
c.test(x);
c.report();
}

Why/When would I want to use a class data member without defining an object of the class?

It is possible in C++ to use a data member of a class without defining an object of that class, by defining that data member in the public section as a static variable, as in the code sample below. The question is, why/when would I want to do this? and how can I do it?
class ttime{
public:
ttime(int h=0, int m=0, int s=0):hour(h), minute(m), second(s){} //constructor with default intialization
int& warning(){return hour;}
void display()const{cout<<hour<<"\t";}
static int hello;
~ttime(){}
private:
int hour;
int minute;
int second;
};
main()
{
ttime:: hello=11310; //Is this the way to use hello without creating an object of the class?
cout << ttime:: hello;
ttime hi(9);
hi.display();
hi.warning()++;//the user is able to modify your class's private data, which is really bad! You should not be doing this!
hi.display();
}
Declaring a class member variable as static essentially makes it a singleton object that is shared by all of the instances of that class. This is useful for things like counters, semaphores and locks, and other types of data that need to be shared by the other class members.
Declaring it public makes it accessible to all users of that class. It's generally a bad idea to allow class variables to be modifiable by functions outside the class, though.
Declaring it const, on the other hand, is the usual way to provide publicly readable constants for the class.
Example
Your library class:
class Foo
{
public:
// Version number of this code
static const int VERSION = 1;
private:
// Counts the number of active Foo objects
static int counter = 0;
public:
// Constructor
Foo()
{
counter++; // Bump the instance counter
...
}
// Destructor
~Foo()
{
counter--; // Adjust the counter
...
}
};
Some client of your library:
class Bar
{
public:
// Constructor
Bar()
{
// Check the Foo library version
if (Foo::VERSION > 1)
std::cerr << "Wrong version of class Foo, need version 1";
...
}
};
In this example, VERSION is a static constant of the class, which in this case informs the outside world what version of the code is contained in the class. It's accessed by the syntax Foo::VERSION.
The static counter variable, on the other hand, is private to the class, so only member functions of Foo can access it. In this case, it's being used as a counter for the number of active Foo objects.
As cited before, static member variables work as 'global' variables, but within the class namespace.
So it is useful for counters or shared resources between objects.
In the case of 'public static' modifier, it is easy to see its use within libraries to provide access to constants and general-purpose functionality (static methods).
For example, an input library might have:
class KeyEvent
{
public:
static const int KEY_DOWN = 111;
static const int KEY_UP = 112;
...
}
//And then in your code
#include <KeyEvent>
void poolEvent(Key *key)
{
if(key->type() == KeyEvent::KEY_DOWN)
...
}
I am not familiar with the c++ syntax for statics at the moment. But in c++-cli (.net, Visual C++) the :: is correct.
For the purpose of statics:
There are many cases where it makes sense to use them. In general, when you want to store information that belong to the class itself (meaning to all objects of the class) and not to a single object/instance.
Even though not originally invented for this purpose, static constexpr data members of structs are a backbone of template meta-programming. Just check out the limits standard library header as a simple example.
For example, we can define a wrapper around the builtin sizeof operator. While rather useless in itself, it hopefully gives the right idea.
#include <iostream>
template<typename T>
struct Calipers
{
static constexpr auto size = sizeof(T);
};
int
main()
{
std::cout << "short: " << Calipers<short>::size << "\n";
std::cout << "int: " << Calipers<int>::size << "\n";
std::cout << "long: " << Calipers<long>::size << "\n";
std::cout << "float: " << Calipers<float>::size << "\n";
std::cout << "double: " << Calipers<double>::size << "\n";
}
Possible output:
short: 2
int: 4
long: 8
float: 4
double: 8
It is similar to a global variable, only that it is not defined at the global namespace.
You find it in C++ code that was written before namespaces were introduced, or in template meta programming were it is more useful.
In general, I would not recommend to use it as in your example and would prefer to avoid global state as much as possible. Otherwise, you end up with code that is difficult to test.

Namespace search order

I have two namespaces that each have a function with the same name. If from one of the namespaces I want to call the function that matches the best. From a function in NamespaceA, if I call MyFunction(...), of course it uses the one in NamespaceA. However, if I add a 'using NamespaceB::MyFunction', I would then expect the behavior I described. However, what I actually see is that it ALWAYS finds the NamespaceB function, even though I am in NamespaceA. HOWEVER, if I ALSO add a using::NamespaceA (even though I am already in NamespaceA), it works as I'd expect. A demonstration is below. Can anyone explain how this works?
#include <iostream>
namespace NamespaceA
{
void DoSomething();
void MyFunction(int object);
}
namespace NamespaceB
{
void MyFunction(float object);
}
namespace NamespaceA
{
void DoSomething()
{
using NamespaceA::MyFunction; // Note that without this line the lookup always fins the NamespaceB::MyFunction!
using NamespaceB::MyFunction;
MyFunction(1);
MyFunction(2.0f);
}
void MyFunction(int object)
{
std::cout << "int: " << object << std::endl;
}
}
namespace NamespaceB
{
void MyFunction(float object)
{
std::cout << "float: " << object << std::endl;
}
}
int main(int argc, char *argv[])
{
NamespaceA::DoSomething();
return 0;
}
It has to do with the order in which different parts of the program are looked in to find a name. For the situation you mention, it has to do with the scope of the function's top-level block being searched for before the enclosing namespace. Basically, the using declaration brings that name into the top-level scope of DoSomething, and since that scope is looked in before the enclosing namespace scope, then if a matching function is found there, then the enclosing namespace scope isn't considered.
I have glossed over a lot of stuff that isn't relevant in your example (for example, if the argument were not a built-in type then, believe it or not, names from the scope where that type was defined could be considered as well. For the whole story, see section 3.4 here. It's pretty scary, about 13 pages to describe all this stuff; but don't bother with it unless you really are curious, because most of the stuff is there so that it "works the way you expect", more-or-less. That document is not the real Standard but actually a working draft with some corrections, so it is basically the real C++ Standard plus some bugfixes.
i believe namespaces use the same scoping rules as variables. so if you have a local namespace, lookups will happen there first before moving to the outer scope.
i'm not sure what the rules are for the situation where you have imported two namespaces with the same function names, but you should always fully qualify the function calls in that scenario just for clarity, instead of relying on some nuance of the language implementation for namespaces that people may not be familiar with.
Short answer: Local defined name and the name declared by a using-declaration hides nonlocal names.
Detailed answer:
Your question is very interesting. I didn't open standarts of C++98,03,11 for that question, but open Bjarne Stroustrup's book
Namespace - is a named scope. Verbosity can be eliminated using two techniques:
create synonymous with using NS :: x; (using-declaration)
create synonymous for all the variables with using namespace NS :: x; (using-directive)
The answer to your question is here:
Appendix B 10.1
local definitions, and names defined with using-declaration hides
the name of a non-local definitions.
Bonus with opposite situation:
Also if you
using NamespaceA::MyFunction;
using NamespaceB::MyFunction;
change to
using namespace NamespaceB;
Then you due to text below get situation with call only void MyFunction(int object)
8.2.8.2
Names explicitly declared in namespace (also made with using declaration)
have priority over the names made available by using directives
Extra code to play with:
#include <iostream>
// var in global namespace
const char* one = "G_one";
// vars in named namespace
namespace NS1 {
const char* one = "NS1_one";
const char* two = "NS1_two";
const char* three = "NS1_three";
}
namespace NS2 {
const char* one = "NS2_one";
const char* two = "NS2_two";
const char* three = "NS2_three";
}
int main(int argc, char *argv[])
{
using namespace NS1; // using-directive
using namespace NS2; // using-directive
// const char* two = "L_two"; // local namespace
using NS2::two; // using-declaration
// C++ rules
// Local names and names with using-declarations
// takes precedence over the name of the NS
std::cout << "two: " << two << std::endl;
//std::cout << "three: " << three << std::endl; // ambiguous symbol
// But the name in global-namespace does not have priority over imported name from namespace
//std::cout << "one: " << one << std::endl; // ambiguous symbol. Because wGlobal names does not have priority over
return 0;
}

What does prepending "::" to a function call do in C++? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is the meaning of prepended double colon “::” to class name?
I have been looking at a legacy C++ code and it had something like this:
::putenv(local_tz_char);
::tzset();
What does this syntax of prepending "::" to the function calls mean? Google-fu is failing me.
It means that the functions putenv() and tzset() will be looked up by the compiler in the global namespace.
Example
#include <iostream>
using namespace std;
//global function
void foo()
{
cout << "This function will be called by bar()";
}
namespace lorem
{
void foo()
{
cout << "This function will not be called by bar()";
}
void bar()
{
::foo();
}
}
int main()
{
lorem::bar(); //will print "This function will be called by bar()"
return 0;
}
Also known as Scope resolution operator
In C++ is used to define the already declared member functions (in the
header file with the .hpp or the .h extension) of a particular class.
In the .cpp file one can define the usual global functions or the
member functions of the class. To differentiate between the normal
functions and the member functions of the class, one needs to use the
scope resolution operator (::) in between the class name and the
member function name i.e. ship::foo() where ship is a class and foo()
is a member function of the class ship.
Example from Wikipedia:
#include <iostream>
// Without this using statement cout below would need to be std::cout
using namespace std;
int n = 12; // A global variable
int main() {
int n = 13; // A local variable
cout << ::n << endl; // Print the global variable: 12
cout << n << endl; // Print the local variable: 13
}
There was a discussion yesterday (+ a year) on a similar question. Perhaps you can find a more indepth answer here.
What is the meaning of prepended double colon "::"?
It means: look up the function in the global namespace.
It will use the specifically unqualified name (as opposed to anything imported with the using keyword).
the :: is the scope resolution operator, it tells the compiler in what scope to find the function.
For instance if you have a function with a local variable var and you have a global variable of the same name, you can choose to access the global one by prepending the scope resolution operator:
int var = 0;
void test() {
int var = 5;
cout << "Local: " << var << endl;
cout << "Global: " << ::var << endl;
}
The IBM C++ compiler documentation puts it like this (source):
The :: (scope resolution) operator is used to qualify hidden names so
that you can still use them. You can use the unary scope operator if a
namespace scope or global scope name is hidden by an explicit
declaration of the same name in a block or class.
The same can be done for methods inside a class and versions of the same name outside. If you wanted to access a variable, function or class in a specific namespace you could access it like this: <namespace>::<variable|function|class>
One thing to note though, even though it is an operator it is not one of the operators that can be overloaded.