Declaring uninitialized variable which is initialized within a nested scope - c++

I have the following C++ snippet
double exetime = 0;
SVDRec R;
{
timer<double> dummy{exetime};
R = svdLAS2();
}
std::cout << exetime << std::endl;
where the constructor of timer records the time the scoping block was entered, and its destructor (which is called when the block is leaved) computes the passed time and stores it in exetime. R is only initialized inside the block, and it does not have a default constructor, so the code doesn't compile for this reason. But I do not want to initialize R to some dummy value.
This, too, doesn't compile:
double exetime = 0;
SVDRec &&tmpR;
{
timer<double> dummy{exetime};
tmpR = svdLAS2();
}
SVDRec R = tmpR;
std::cout << exetime << std::endl;
I know I could use a pointer but I do not want to use dynamic allocation nor std::unique_ptr. Is there is anyway to achieve this?

You can try:
double exetime = 0;
SVDRec R = [&exetime]()
{
timer<double> dummy{exetime};
return svdLAS2();
}();
std::cout << exetime << std::endl;

Related

How to get value from a vector by value from another vector?

I have two vectors:
one contains numbers and names of things;
second collects numbers that have already been showed to the user;
I'm trying to make a history list of all objects that have been shown.
Here is my code:
class palettArchive{
private:
std::vector<std::pair<int,std::string>> paletts;
int palletsCounter;
std::vector<int> choosen;
public:
//...
void history(){
auto printHist = [](int& i){
int tmp = i;
std::pair<int,std::string> tempPair = paletts[tmp];
std::cout << tempPair.first << " " << tempPair.second;
return 0;
};
std::for_each(choosen.begin(), choosen.end(), printHist);
}
};
There is an error:
error: 'this' cannot be implicitly captured in this context
std::pair<int,std::string> tempPair = paletts[tmp];
I can't make a third vector with the list that is created already. I need to make it by calling a function and printing at the time.
The lambda must capture this to be able to access member variables:
auto printHist = [this](int& i){ ... };
for_each and lambda are just making your life difficult. The simpler code is explicit iteration:
void history()
{
for (auto i : choosen) {
auto tempPair = paletts[i];
std::cout << tempPair.first << " " << tempPair.second;
// did you mean to send a newline "\n" also?
}
}

Can anybody explain me why this code is not working?

I'm learning C++. Now, I'm trying to make one sample related with overloading operators of an object. My object (called Contador) has different methods and variables which help user to count iterations.
Header file of the object:
class Contador
{
private:
int* Valor;
int* Salto;
public:
Contador(int Valor_Inicio = 0, int Salto = 1);
~Contador();
inline int Get_Valor() const { return *Valor; }
inline int Get_Salto() const { return *Salto; }
inline void Incremento() { Set_Valor(Get_Valor() + Get_Salto()); }
inline void operator++ () { Set_Valor(Get_Valor() + Get_Salto()); }
void Set_Valor(int Valor);
void Set_Salto(int Salto);
};
Cpp file of the object:
// Librerias Propias
#include "Contador.h"
Contador::Contador(int Valor_Inicio, int Salto)
{
Set_Valor(Valor_Inicio);
Set_Salto(Salto);
}
Contador::~Contador()
{
delete Contador::Valor;
delete Contador::Salto;
}
void Contador::Set_Valor(int Valor)
{
delete Contador::Valor;
Contador::Valor = new int(Valor);
}
void Contador::Set_Salto(int Salto)
{
delete Contador::Salto;
Contador::Salto = new int(Salto);
}
The main() function of the sample has 2 different for loops. In the first one, I call Incremento() method and in the second one I call the overloaded operator.
Main function:
void main()
{
// Genero el elemento de analisis.
Contador* contador = new Contador();
// Realizo el bucle con la funciĆ³n de incremento.
std::cout << "Incremento()" << std::endl;
for (contador->Set_Valor(0); contador->Get_Valor() < 3; contador->Incremento())
{
// Escribo algo.
std::cout << "Iteracion actual: " << contador->Get_Valor() << std::endl;
}
// Realizo el bucle on el operador sobrecargado
std::cout << "operador sobrecargado" << std::endl;
for (contador->Set_Valor(0); contador->Get_Valor() < 3; contador++)
{
// Escribo algo.
std::cout << "Iteracion actual: " << contador->Get_Valor() << std::endl;
}
}
The problem appears when main function passes the first iteration of the second loop. It throws one exception in Get_Valor() method.
It seems to me that it change the memory addres of the pointer Valorin some place, but I can`t find where.
Can anybody help me?
Thanks.
contador++ does not do what you think it does - contador is a pointer, not a Contador, so it will make contador point to something that does not exist.
You need to dereference the pointer.
However, *contador++ also increments contador - it is *(contador++) - and (*contador)++ does not compile because you have only overloaded the prefix operator (the postfix operator has the prototype operator++(int).
So, ++*contador will do what you want.
You can avoid many similar problems, and the clunky syntax, by not using pointers unnecessarily.
The expression contador++ increments the address that contador (a pointer) points to! So, after the first iteration, the pointer will be completely invalid.
To call the increment operator, you need: ++(*contador) which first dereferences the pointer to the object pointed to, then effects that object's increment operator.
3 coding issues:
main shoudl return int.
Valor and Salto are not initialized in constructor.
Contador::Set_Valor and Contador::Set_Salto requires initialized pointers (as you delete them).
Easy fix is:
class Contador
{
private:
int* Valor = nullptr;
int* Salto = nullptr;
//...
};
Last issue is in your last loop:
for (contador->Set_Valor(0); contador->Get_Valor() < 3; contador++)
As condator is a pointer (not pointing on an array), accessing condator[1] would be UB.
You wanted ++(*condator) (operator++ () is pre-increment whereas operator++ (int) is post-increment).
Finally, avoiding usage of all those pointers would simplify code (and no bother with rule of 3 you break):
class Contador
{
private:
int Valor;
int Salto;
public:
Contador(int Valor = 0, int Salto = 1) : Valor(Valor), Salto(Salto) {}
~Contador() = default;
int Get_Valor() const { return Valor; }
int Get_Salto() const { return Salto; }
void Incremento() { Set_Valor(Get_Valor() + Get_Salto()); }
void operator++ () { Set_Valor(Get_Valor() + Get_Salto()); }
void Set_Valor(int Valor) { this->Valor = Valor;}
void Set_Salto(int Salto) { this->Salto = Salto;}
};
int main()
{
Contador contador;
std::cout << "Incremento()" << std::endl;
for (contador.Set_Valor(0); contador.Get_Valor() < 3; contador.Incremento())
{
std::cout << "Iteracion actual: " << contador.Get_Valor() << std::endl;
}
std::cout << "operador sobrecargado" << std::endl;
for (contador.Set_Valor(0); contador.Get_Valor() < 3; ++contador)
{
std::cout << "Iteracion actual: " << contador.Get_Valor() << std::endl;
}
}
In addition to previous answers.
As I could see Contador* contador = new Contador(); code also contains UB (undefined behaviour)
This call is equal to constructor with parameters Contador(0, 1)
which will do Set_Valor and Set_Salto which call delete first but at this moment content of this variables is not guaranteed to be nullptr so you might corrupt data. Also compiler if it sees UB might optimize out all other code since it's already UB and it can change behaviour anyway it wants for example throw it away completely. https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633

std::vector initialization in another function

I need to initialize vectors and check whether the initialization has been successful many times, so I decided to create a function for that. The problem is that I haven't been able to find a way to tackle this problem without losing a significant amount of efficiency. This has been my attempt so far:
#include <iostream>
#include <vector>
bool init(std::vector<double>& v, int n, double x) {
try {
v = std::vector<double>(n, x);
}
catch (std::bad_alloc& e) {
std::cerr << "Error: " << e.what() << std::endl;
return false;
}
return true;
}
int main() {
int n = -1;
std::vector<double> v;
if (not init(v, n, 1)) {
std::cerr << "Vector failed to initialize" << std::endl;
}
else {
for (int i = 0; i < n; ++i) {
std::cout << v[i] << std::endl;
}
}
}
Notice that I create a new vector and then call the copy constructor, so the cost is similar to initializing two vectors instead of one. Is there an efficient alternative to this?
Notice that I create a new vector and then call the copy constructor, so the cost is similar to initializing two vectors instead of one.
I do not think so.
You create an empty std::vector<double> v, which is a relatively cheap operation, and then assign it a new value inside init().
However, in init() a temporary std::vector<double>(n, x) is assigned to v, so the move assignment operator, not the copy constructor, will be called and no unnecessary copying is performed.
You cannot initialize something after it has been constructed. However, the simplest "solution" to your "problem" is to construct the vector in place instead of using an "init" function with an "output parameter".
int main() {
int n = -1;
try
{
std::vector<double> v(n, 1);
for (int i = 0; i < n; ++i) {
std::cout << v[i] << std::endl;
}
}
catch(const std::bad_alloc&)
{
std::cerr << "Vector failed to initialize" << std::endl;
}
}
If you really need an "init" function for your vector, then return by value and use it to initialize something at the caller side.
std::vector<double> init(int n, double x) {
return std::vector<double>(n, x);
}
Both versions leave you with less things to think about. For example, you don't have to instantiate and empty vector first, then check the return value of a function (which you can easily neglect to do) and you don't have to document what happens if a non-empty vector gets passed, or read the documentation if you're the user of the function.

How to use values created inside a loop function?

I would like to know which one would be the best way of using values created inside a loop, outside of that loop. I have for example the function:
void Loop(int a)
{
// recursion loop execution
for ( int i = 0; i < 10; i++ )
{
int new_a = a + i;
}
}
I would like to use that "new_a" as it is being "looped" in another function which is plotting a graph and only needs the "yAxe" value. Like that:
int main ()
{
int a = 5;
plot (x,Loop(int a);
}
I know I could create an array with the values of the loop but I wouldn't like to store them and for big plottings would be too much memory.
Any local variable will be destroyed when the scope of them be finished. For example, in your code new_a will be destroyed when the for loop is finished, and the a is destroyed when the function be finished. I mean if you care about memory, don't be worry.
If I understand you correctly, you want to call Loop multiple times (like e.g. Loop(a)) and each call you should get the next "iteration" of the loop?
That would have been easy if C++ had continuations which it doesn't. Instead it can be emulated by using classes and objects and operator overloading.
For example:
class LoopClass
{
public:
LoopClass(int initial_value = 0)
: current_value{initial_value}
{
}
int operator()(int a)
{
return a + current_value++;
}
private:
int current_value;
};
It can be used as such:
LoopClass Loop; // The value initialized with zero
int a = 5;
std::cout << "First call : " << Loop(a) << '\n';
std::cout << "Second call: " << Loop(a) << '\n';
The above code, if put into a program, should print
First call : 5
Second call: 6

How/Can C++ lambdas retain inner state?

I have a basic lambda that looks like this:
auto l = [](){
int i = 0;
cout << i++;
}
Calling this a bunch of times, will keep printing 0. How can I retain i? Can I do this without functors?
Depending on what you want to do with this lambda, you might consider the following alternative:
auto exec = [i = 0]() mutable { cout << ++i << ' '; };
exec(); // 1
exec(); // 2
auto exec2 = exec; // copy state of lambda
exec2(); // 3
exec(); // 3
Using []() { static int i = 0; cout << ++i << ' '; }; instead will result in the sequence 1 2 3 4 being printed.
Live example
Try to think of a lambda as a class with an operator(). How would you retain state in a class? Have a member. Captures are the equivalent here.
#include <iostream>
auto l = [i=0]()mutable{
std::cout << i++;
};
auto l2=l;
int main(){
l(); // 0
l(); // 1
l(); // 2
l2(); // 0
l2(); // 1
l(); // 3
std::cout << '\n';
}
auto l = [](){
static int i = 0;
// ^^^^^^
cout << i++;
}
should fix your concerns.
In general functions cannot retain inner state without using a local static variable. There's no difference with using lambdas actually.
If you want to count copies, you can use an ordinary functor class implementation as #Revolver_Ocelot suggested.
If you want i to retain its value then you have three options:
Declare i as a global variable (Bad).
Pass previous value of i to the function every time (Better).
Declare i as a static variable (Best).
auto l = []() { static int i = 0; cout << i++ << endl; };
l(); l(); l();
This will give as output:
0
1
2