Please assume the version of gcc 7.2.1 in this question
I would like to declare a global variable which behave like a const however, the value to initialize it cannot not be detected before the program being executed. In other words, the target variable would be re-assigned since the first time it is assigned.
An ugly approach of this concept as follow:
#include<iostream>
int numberOfPeople; //Do not re-assign it after it first assign
int main(){
std::cin >> numberOfPeople; // Do not re-assign numberOfPeople since then !!!
// Following of codes omitted.
}
As you could see, this is a very ugly approach and cannot be checked by compiler. I wonder whether there is a kind of notation in c++ that can freeze the variable since it first assigned.
So I can write code like this:
#include<iostream>
magic_notation int numberOfPeople;
int main(){
std::cin >> numberOfPeople; // Allowed as it's first assign.
// Median codes omitted.
numberOfPeople = 60. //Disallowed and will get an error message from compiler!
// Following codes omitted.
}
Is there any kind of notation as can use like the magic_notation in the code above in c++?
The best approach is to make a class with a public const member variable which gets initialized in the constructor:
struct InitInfo {
const int numberOfPeople;
InitInfo() numberOfPeople(getNumberOfPeople()) {
}
private:
static int getNumberOfPeople() {
int res;
cin >> res;
return res;
}
};
InitInfo initInfo;
Now you can use the member variable as follows:
int main() {
cout << initInfo.numberOfPeople << endl;
}
You can use the same approach for initializing a global variable, too.
static int getNumberOfPeople() {
int res;
cin >> res;
return res;
}
const int numberOfPeople = getNumberOfPeople();
int main() {
cout << numberOfPeople << endl;
numberOfPeople += 10; // <<== This triggers an error
}
One approach you can use is to wrap the variable as a static variable in a function. Use the function instead of the variable in rest of your code.
#include <iostream>
int readFromStdin()
{
int n;
cin >> n;
return n;
}
// Wrap it arund in a function.
// int numberOfPeople; //Do not re-assign it after it first assign
int getNumberOfPeople()
{
// Initialize by reading from stdin.
static int numberOfPeople = readFromStdin();
returnn numberOfPeople;
}
int main(){
// Use the function instead of the variable.
getNumberOfPeople();
}
In case you have different ways to initialize the variable, you could come up with something like this:
struct {
int value() const { return _val; }
void init(int val) {
if(!_set) _val = val;
}
private:
int _val;
bool _set = false;
} numberOfPeople;
Now, everybody who uses the variable should call init before using it to make sure it is initialized.
Related
i want to take an input from c++ function and return it to the main function
, i've already tried to do it but the function returns zero , any idea ?
#include<iostream>
using namespace std;
int input( int x);
int main()
{
int number;
input(number);
cout<<number;
}
int input (int x)
{
cin>>x;
return x;
}
you need to pass by reference
void input (int & x)
{
cin>>x;
}
or use the return value
int main()
{
int number;
number = input();
cout<<number;
}
int input ()
{
cin>>x;
return x;
}
You can change your function to make it take x by reference:
void input (int& x)
{
cin>>x;
}
This way, you don't even need to return x, because your function will update its value as it is passed by reference.
So, let's get it from the begining :
It any function, all its variables are temporary and only accessible in this function's scope unless you use a pointer or a reference(c++ only)
So what happen when you call your function is that a copy of number's is created into x
Also, the return statement of a function is used to... return values! Yeah, weird uh?
So actually you don't even need to send any parameter to your function and just take its result :
#include<iostream>
using namespace std;
int input();
int main()
{
int number = input(); // Takes what the return statement gives
cout<<number;
}
int input ()
{
int x;
cin>>x;
return x;
}
Here's another way by using c++'s references :
#include<iostream>
using namespace std;
void input( int& x);
int main()
{
int number;
input(number);
cout<<number;
}
int input (int& x)//Takes number's address
{
cin>>x;
}
How correctly declare pointers, allocate memory, and send them as parameters in fuctions to write values ? The code below is what I tried but it doesn't work correctly. I need the same logic. I mean declare, set, then show.
...
struct complex {
int i;
int r;
};
void set(complex *n, int i, int r){
n = new complex;
n->i = i;
n->r = r;
}
void show(complex *n){
std::cout << n->i << " " << n->r;
}
int main(int argc, char* argv[])
{
complex *n;
set(n,10,20);
show(n);
system("pause");
return 0;
}
Actually, your function set couldn't work, because by doing
n = new complex;
whatever the pointer you pass to the function, the pointer will be overwritten by the pointer on the new object.
You can pass the pointer via reference (on C++ only...) like that
void set(complex* &n, int i, int r)
And by doing so you'll modify the value of the original pointer.
You can also simply return the pointer by a return n
But obviously if the prototype of your function must stay like that, it's not possible...
Or, but it's highly discouraged, as many said, you can use a double pointer, and it's quite tricky !
If I don't make mistake, you create a
complex** n
You pass it to your function
set(complex** n, int i, int r)
And then you load
*n = new complex
And it must work if you pass *n to all your function instead of n...
And don't forget to delete your object at the end ;)
Remove the initialization part from set function and put it in the main function.
see this link for explanation.
Why can I not initialize an array by passing a pointer to a function?
Check this code
//#include<windows.h>
#include <iostream>
using namespace std;
struct complex {
int i;
int r;
};
void set(complex *n, int i, int r) {
// n = new complex;
n->i = i;
n->r = r;
}
void show(complex *n) {
std::cout << n->i << " " << n->r;
}
int main(int argc, char *argv[]) {
complex *n = new complex();
set(n, 10, 20);
show(n);
delete n;
//system("pause"); TRY TO AVOID THIS. MAKES YOUR CODE LESS PORTABLE.
return 0;
}
see this link.
c++ - system("pause"); - Why is it wrong? - Stack Overflow
In some occasions, I may need to use the same behavior/code, with values that sometimes are known at run-time and at compile-time. This leads to code repetition:
template<int TValue> struct CompileTime
{
int duplicate() { return TValue * 2; }
};
struct RunTime
{
int value;
RunTime(int mValue) : value{mValue} { }
int duplicate() { return value * 2; }
};
int main()
{
// I need to duplicate a compile-time known value first...
CompileTime<2>{}.duplicate();
// And now I need to duplicate a run-time value...
int value; std::cin >> value;
RunTime{value}.duplicate();
}
Obviously the example is really stupid, but is there any way I can avoid repeating the behavior of duplicate()? (The value needs to be stored, however.)
Ideally, I'd like to write:
int main()
{
// 2 is known at compile-time, calls a "templatized" version of `duplicate`
UnknownTime<2>{}.duplicate();
// `value` is known at run time, calls a "run-time" version of `duplicate`
int value; std::cin >> value;
UnknownTime<value>{}.duplicate();
}
You cannot make templates instantiate at runtime, you can however ditch templates altogether and use c++11 constexpr, which was added to the language exactly for this purpose:
struct AnyTime
{
int value;
constexpr AnyTime(int mValue) : value{mValue} { }
constexpr int duplicate() const { return value * 2; }
};
int main()
{
constexpr int compileTime = AnyTime{2}.duplicate();
int value; std::cin >> value;
int runTime = AnyTime{value}.duplicate();
}
In cases like duplicate you could move to using functions, rather than classes or structures:
template<int TValue>
int duplicate()
{
return TValue * 2;
}
int duplicate(int value)
{
return value * 2;
}
Now you can say:
int main()
{
// 2 is known at compile-time, calls a "templatized" version of `duplicate`
int value1 = duplicate<2>();
// `value` is known at run time, calls a "run-time" version of `duplicate`
int value; std::cin >> value;
int value2 = duplicate(value);
}
My program simply is to increase the salary int the emp class throw the the function increase
but I'm having this error int the call function line from the line :
No suitable constructor to convert from int to emp
here 's my code :
#include <iostream>
#include <string>
using namespace std;
class emp
{
public:
int salary;
};
void increase(emp x,emp y)
{
x.salary+=100;
y.salary+=250;
}
int main()
{
int value=0;
emp fst, scnd;
cin >> fst.salary >> scnd.salary;
increase(fst.salary,scnd.salary);
cout << fst.salary << endl << scnd.salary << endl;
cin >> value;
return 0;
}
increase expects two emps as parameters, yet you pass in two ints.
Change
increase(fst.salary,scnd.salary);
to
increase(fst,scnd);
Your next question is going to be why the values don't change, so to save you the trouble - it's because you're passing by value, effectively changing copies of your original objects. You'll need to pass by reference:
void increase(emp& x,emp& y)
increase(fst.salary,scnd.salary); should be increase(fst,scnd);, void increase(emp x,emp y) ... should be void increase(emp& x,emp& y) ...
You need to pass emp not int. Further, you are passing parameters by value. Use this instead:
void increase(emp &x,emp &y)
And pass the struct variables; i.e. fst and scnd instead of fst.salary and scnd.salary. Refer this question for better understanding.
I know the answer is 99.99% no, but I figured it was worth a try, you never know.
void SomeFunction(int a)
{
// Here some processing happens on a, for example:
a *= 50;
a %= 10;
if(example())
a = 0;
// From this point on I want to make "a" const; I don't want to allow
// any code past this comment to modify it in any way.
}
I can do something somewhat similar with const int b = a;, but it's not really the same and it creates a lot of confusion. A C++0x-only solution is acceptable.
EDIT: another less abstracted example, the one that made me ask this question:
void OpenFile(string path)
{
boost::to_lower(path);
// I want path to be constant now
ifstream ...
}
EDIT: another concrete example: Recapture const-ness on variables in a parallel section.
One solution would be to factor all of the mutation code into a lambda expression. Do all of the mutation in the lambda expression and assign the result out to a const int in the method scope. For example
void SomeFunction(const int p1) {
auto calcA = [&]() {
int a = p1;
a *= 50;
a %= 10;
if(example())
a = 0;
..
return a;
};
const int a = calcA();
...
}
or even
void SomeFunction(const int p1) {
const int a = [&]() {
int a = p1;
a *= 50;
a %= 10;
if(example())
a = 0;
..
return a;
}();
...
}
You could move the code to generate a into another function:
int ComputeA(int a) {
a *= 50;
a %= 10;
if (example())
a = 0;
return a;
}
void SomeFunction(const int a_in) {
const int a = ComputeA(a_in);
// ....
}
Otherwise, there's no nice way to do this at compile time.
A pattern I used to use is to "hide" the argument with an _, so the code becomes
void SomeFunction(int _a)
{
// Here some processing happens on a, for example:
_a *= 50;
_a %= 10;
if(example())
_a = 0;
const int a = _a;
// From this point on I want to make "a" const; I don't want to allow
// any code past this comment to modify it in any way.
}
You could also use only const variables and make a function to compute the new value of a, if necessary. I tend more en more to not "reuse" variables en make as much as possible my variables immutable : if you change the value of something , then give it a new name.
void SomeFunction(const int _a)
{
const int a = preprocess(_a);
....
}
Why not refactor your code in to two separate functions. One that returns a modified a and another that works on this value (without ever changing it).
You could possibly wrap your object too around a holder class object and work with this holder.
template <class T>
struct Constify {
Constify(T val) : v_( val ) {}
const T& get() const { return v_; }
};
void SomeFuncion() {
Constify ci( Compute() ); // Compute returns `a`
// process with ci
}
Your example has an easy fix: Refactoring.
// expect a lowercase path or use a case insensitive comparator for basic_string
void OpenFile(string const& path)
{
// I want path to be constant now
ifstream ...
}
OpenFile( boost::to_lower(path) ); // temporaries can bind to const&
this might be one way to do it, if you are just trying to avoid another name. i suggest you think twice before using this.
int func ()
{
int a;
a %= 10;
const int const_a = a;
#define a const_a
a = 10; // this will cause an error, as needed.
#undef a
}
I don't actually suggest doing this, but you could use creative variable shadowing to simulate something like what you want:
void SomeFunction(int a)
{
// Here some processing happens on a, for example:
a *= 50;
a %= 10;
if(example())
a = 0;
{
const int b = a;
const int a = b; // New a, shadows the outside one.
// Do whatever you want inside these nested braces, "a" is now const.
}
}
Answers were pretty solid, but honestly I can't really think of a GOOD situation to use this in. However in the event you want to Pre-Calculate a constant which is basically what you are doing you have a few main ways You can do this.
First we can do the following. So the compiler will simply set CompileA# for us in this case it's 50, 100, and 150.
const int CompileA1 = EarlyCalc(1);
const int CompileA2 = EarlyCalc(2);
const int CompileA3 = EarlyCalc(3);
int EarlyCalc(int a)
{
a *= 50;
return a;
}
Now anything beyond that there's so many ways you can handle this. I liked the suggestion as someone else had mentioned of doing.
void SomeFunc(int a)
{
const int A = EarlyCalc(a);
//We Can't edit A.
}
But another way could be...
SomeFunc(EarlcCalc(a));
void SomeFunc(const int A)
{
//We can't edit A.
}
Or even..
SomeFunction(int a)
{
a *= 50;
ActualFunction(a);
}
void ActualFunction(const int A)
{
//We can't edit A.
}
Sure, there is no way to do it using the same variable name in C++.