vendredi 30 septembre 2022

How to see the contents of a C++ struct?

I am running this example . I want to know the contents of

WasmEdge_ASTModuleContext *ASTCxt

WasmEdge_ASTModuleContext is a structure. Is there any way ? Like can I print it just to see how it looks.?

use std::string to call a function in C++11

I want to use string value to call a function. Is this possible? Can someone please show some implementation. I would appreciate it.

class obj {
    int num1;
    int num2;
}

int func1(obj o) {
   return o.num1 + o.num2;
}

std::map<std::string, std::string> funcNameMap = ;

int someFunction(std::string funcName, obj o) {
    // Get the value associated with the string "funcName" i.e. "func1". 
    // Calls function "func1" with value "o" and returns the value.
}

int main(){
   obj o;
   o.num1 = 1;
   o.num2 = 2;
   auto x = someFunciton("func1", o);
   std::cout << x << std::endl;
   return 0;
}


/usr/bin/ld: cannot find -lstdc++ when trying to statically link

I am trying to compile a simple program statically. I keep getting the following error:

$ g++ -std=c++11 main.cpp -static
  /usr/bin/ld: cannot find -lstdc++
  /usr/bin/ld: cannot find -lm
  /usr/bin/ld: cannot find -lc

I removed pieces of code until I got down to the complete barebones:

int main(int argc, char** argv)
{
    return 0;
}

Googling and looking on here haven't proven fruitful. How can I fix this problem?

Storing pointer to functions in a map

Can anyone explain why this piece of code is generating the error as shown below. I am trying to store pointer to function in a map. The code would work fine if I keep everything in main() function. Also I would appreciate it if someone shows how to fix it.

#include <boost/variant.hpp>
#include <map>
#include <iostream>
#include <map>
using namespace boost;
class obj {
public:
    int num1;
    int num2;
    std::string s1;
    std::string s2;
};
typedef boost::variant<int, float, double, std::string> MultiType;
typedef MultiType(*FnPtr)(obj);

        
        
class c {
public:
    MultiType add(obj o);
    std::map<std::string, FnPtr> metricToFuncMap = { { "i", add } };
};
MultiType c::add(obj o) {
    { MultiType x;  x = o.num1 + o.num2; return x; }
}

int main() {
    obj o;
    //add
    MultiType d;
    d = 1;
    o.num1 = 1;
    o.num2 = 2;
    //concat
    o.s1 = "hello";
    o.s2 = "world";
    c c;
    MultiType x = c.metricToFuncMap["i"](o);
    std::cout << get<int>(x);
    return 0;
}

Error:

E0289   no instance of constructor "std::map<_Kty, _Ty, _Pr, _Alloc>::map [with _Kty=std::string, _Ty=FnPtr, _Pr=std::less<std::string>, _Alloc=std::allocator<std::pair<const std::string, FnPtr>>]" matches the argument list     

jeudi 29 septembre 2022

Getting(Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH) when calling function from vb.net to cpp

when I am trying to call the function from VB.net to cpp the above exception is seen. This was working fine when I call from vbs to cpp. Please find a below code:

Sample.vb

Public Function gettingLock(ByRef loids_out As Object, ByRef modes_out As Object, ByRef ids_out As Object, ByRef flags_out As Object) As Object

    Dim aLoids As Object
    Dim aModes As Object
    Dim aIds As Object
    Dim aFlags As Object
    
    pxdb.getLockInformation(aLoids, aModes, aIds, aFlags)

Sample.cpp

STDMETHODIMP CPXDBServer::getLockInformation(InterCollection **loids, InterCollection **modes, InterCollection **ids, InterCollection **flags) {

}

While calling getLockInformation () from Sample.vb to Sample.cpp getting Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH)

Can someone explain to me what this means? for(int i {n}; i > 0; i--)

Someone wrote for (int i {n}; i > 0; i--) in their solution, I can't find what the {n} means. Could someone please explain it?

C++: This world object constructor doesn't seem to be doing what I want it to and the play method is crashing the program with a seg fault error

I have a world class that creates a level* array, creating a new level for each spot in the level* array. After each level object is created a boss* element is added to the level object's Element* array(all elements in the array are derived classes of the element class), and a warpipe* element is added to the level object's level array for every level object except the last one. Additionally, a Mario* element is created and added to the first level's object array. For all additions to the level object array, after the level is created(Boss, Warpipe, Mario), a check is done to make sure the element in the array being replaced is a nothing element.

Once the world is created the play function is called. This method runs as long as Mario still has lives and the current level int exists as an index in the level* array. For each iteration of the loop, the type of element in the element* array, that Mario is to interact with, is determined, and based on that some action is taken. Afterward, the element Mario interacted with is either reallocated to the current element* in the array, or the current element* now points to a new nothing element. Then, Mario's coordinates are updated and the next type of element in the element* array, that Mario is to interact with, is determined.

I've noticed 2 problems(which may be related to each other), but I can't figure out the reason for either.

The first problem is that the level* array does not construct the level properly

The second problem is that the play method crashes with a seg fault.

Here is my code

World

#ifndef WORLD_H
#define WORLD_H

#include <random>
#include <iostream>
#include "Level.h"
#include "Mario.h"
#include "Boss.h"
#include "WarpPipe.h"

using namespace std;

class World{
public:
    World(int levs, int dim, int livs, int coinPrct, int goombaPcrt, int koopaPrct, int mushPcrt, int nothPcrt);

    ~World();

    void play();

    void nextElement();

    void replaceWithNothing();

    void putBack();

    void warp();

    friend ostream &operator<<(ostream &out, const World &world);
private:
    int m_currentLev;
    int m_totalLevs;
    int m_dim;
    Level **m_levels;
    Element *m_tempElement;
    Mario *m_mario;
};

#endif


#include "World.h"

World::World(int levs, int dim, int livs, int coinPrct, int goombaPcrt, int koopaPrct, int mushPcrt, int nothPcrt){
    
    mt19937 rand(time(nullptr));
    
    m_totalLevs = levs;
    m_currentLev = 0;
    m_dim = dim;
    m_levels = new Level*[m_totalLevs];

    for (int i = 0; i < levs; i++){
        m_levels[i] = new Level(dim, coinPrct, goombaPcrt, koopaPrct, mushPcrt, rand);

        m_tempElement = m_levels[i]->getElement((rand() % dim), (rand() % dim));//tempElement now points to the same element as a random element pointer in the array
        while ( (strcmp(typeid(*m_tempElement).name(), "7Nothing")) != 0){
            m_tempElement = m_levels[i]->getElement((rand() % dim), (rand() % dim));
        }
        m_levels[i]->repopulate(new Boss(m_tempElement->getRow(), m_tempElement->getCol()), m_tempElement->getRow(), m_tempElement->getCol());//the element pointer in the array now points to a new boss object. tempElement still points to the old object
        delete m_tempElement; //if the object is not gonna be placed back in the level array delete it

        
        if (i < levs - 1){

            m_tempElement = m_levels[i]->getElement((rand() % dim), (rand() % dim));//tempElement now points to the same element as a random element pointer in the array
            while ( (strcmp(typeid(*m_tempElement).name(), "7Nothing")) != 0){
                m_tempElement = m_levels[i]->getElement((rand() % dim), (rand() % dim));
            }
            m_levels[i]->repopulate(new WarpPipe(m_tempElement->getRow(), m_tempElement->getCol()), m_tempElement->getRow(), m_tempElement->getCol());
            delete m_tempElement;
        }
    }

    m_tempElement = m_levels[m_currentLev]->getElement((rand() % dim), (rand() % dim));//tempElement now points to the same element as a random element pointer in the array
    while ( (strcmp(typeid(*m_tempElement).name(), "7Nothing")) != 0){
        m_tempElement = m_levels[m_currentLev]->getElement((rand() % dim), (rand() % dim));
    }

    m_mario = new Mario(livs, m_tempElement->getRow(), m_tempElement->getCol());
    m_levels[m_currentLev]->repopulate(m_mario, m_mario->getRow(), m_mario->getCol());

    cout << *this << endl;

    cout << "construction over" << endl;
}

void World::play(){
    while (m_mario->getLives() > 0 && m_currentLev < m_totalLevs){
        cout << *m_levels[m_currentLev] << endl;
        string type = typeid(*m_tempElement).name();
        if (strcmp(type.c_str(),"4Coin")){
            m_mario->collectCoin();
            replaceWithNothing();
        } else if (strcmp(type.c_str(),"8Mushroom")){
            m_mario->increasePower();
            replaceWithNothing();
        } else if (strcmp(type.c_str(),"6Goomba")){
            //interatc with the enemy
            //if win point level array pointer to new nothing object delete what tempElement was pointing to
            //if lose(not including exception) point level array pointer back to object being pointed at by tempelement
            bool win = static_cast<Goomba*>(m_tempElement)->fight(m_mario);
            if (win){
                replaceWithNothing();
            } else {
                putBack();
            }
        } else if (strcmp(type.c_str(),"5Koopa")){
            //interatc with the enemy
            //if win point level array pointer to new nothing object delete what tempElement was pointing to
            //if lose(not including exception) point level array pointer back to object being pointed at by tempelement
            bool win = static_cast<Koopa*>(m_tempElement)->fight(m_mario);
            if (win){
                replaceWithNothing();
            } else {
                putBack();
            }
        } else if (strcmp(type.c_str(),"4Boss")){
            // interact with the boss
            bool win = static_cast<Boss*>(m_tempElement)->fight(m_mario);
            if (win){
                if (m_currentLev == m_totalLevs - 1){//did we beat the boss on the last level
                    replaceWithNothing();
                    m_currentLev++;
                } else {// if its not the last level
                    replaceWithNothing();
                    warp();
                }
            }
        } else if (strcmp(type.c_str(),"8WarpPipe")){
            //warp
            replaceWithNothing();
            warp();
        } else {//Nothing object
            //realoocating the pointer in the array back to the old object because it was a nothing object
            //temp element can now be realocated again
            putBack();
        }

        if (m_currentLev < m_totalLevs){
            nextElement();//tempelement is pointed at the the next object to interact with. the pointer in the array is now pointing at mario
        }
    }

}

void World::nextElement(){
    int next = rand() % 4;
    switch (next){
    case 0://up
        m_tempElement = m_levels[m_currentLev]->getElement((m_mario->getRow() - 1 + m_dim) % m_dim, m_mario->getCol());
        m_levels[m_currentLev]->repopulate(m_mario, m_tempElement->getRow(), m_tempElement->getCol());
        break;
    case 1://down
        m_tempElement = m_levels[m_currentLev]->getElement((m_mario->getRow() + 1 + m_dim) % m_dim, m_mario->getCol());
        m_levels[m_currentLev]->repopulate(m_mario, m_tempElement->getRow(), m_tempElement->getCol());
        break;
    case 3://left
        m_tempElement = m_levels[m_currentLev]->getElement(m_mario->getRow(), (m_mario->getCol() - 1 + m_dim) % m_dim);
        m_levels[m_currentLev]->repopulate(m_mario, m_tempElement->getRow(), m_tempElement->getCol());
        break;
    case 4://right
        m_tempElement = m_levels[m_currentLev]->getElement(m_mario->getRow(), (m_mario->getCol() + 1 + m_dim) % m_dim);
        m_levels[m_currentLev]->repopulate(m_mario, m_tempElement->getRow(), m_tempElement->getCol());
        break;
    default:
        break;
    }
}

void World::replaceWithNothing(){
    m_levels[m_currentLev]->repopulate(new Nothing(m_mario->getRow(), m_mario->getCol()), m_mario->getRow(), m_mario->getCol());
    delete m_tempElement;
}

void World::putBack(){
    m_levels[m_currentLev]->repopulate(m_tempElement, m_mario->getRow(), m_mario->getCol());
}

void World::warp(){
    m_currentLev++;
    m_mario->setCords((rand() % m_dim), (rand() % m_dim));
    while (!(strcmp(typeid(*m_levels[m_currentLev]->getElement(m_mario->getRow(), m_mario->getCol())).name(), "7Nothing"))){
        m_mario->setCords((rand() % m_dim), (rand() % m_dim));
    }
}

ostream &operator << (ostream &out, const World &world){
    for (int i = 0; i < world.m_totalLevs; i++){
        out << *world.m_levels[i] << endl;
    }
    return out;
}

World::~World(){
    delete[] m_levels;
}

int main(int argc, char const *argv[])
{
    World world1(3, 10, 3, 23, 23, 23, 23, 8);
    world1.play();
    //cout << world1 << endl;
    return 0;
}

Level

#ifndef LEVEL_H
#define LEVEL_H

#include <random>
#include <iostream>
#include <algorithm>
#include "Element.h"
#include "Mario.h"
#include "Coin.h"
#include "Mushroom.h"
#include "Goomba.h"
#include "Koopa.h"
#include "Nothing.h"

using namespace std;

//Class for level
class Level{
public:
    //Constructor for level, which takes in the array dimensions
    //Also takes in the percentages chosen by the file, for how many coins, nothing spaces, goomba and koopa's
    //are present in the array (world)
    Level(int dimension, int coinPrct, int goombaPcrt, int koopaPrct, int mushPcrt, mt19937& rand);
    
    //Default destructor
    ~Level();

    void repopulate(Element *elem, int row, int col);

    Element* getElement(int row, int col);

    int getDimension();

    friend ostream &operator<<(ostream &out, const Level &level);
    
//Private member variables
private:
    Element **m_levelAry;
    int m_coins;
    int m_goombas;
    int m_koopas;
    int m_mushrooms;
    int m_dimension;
};

#endif



#include "Level.h"

//Constructor handles dimensions of the array and odds of how frequent coins, enemies and nothing spawn
Level::Level(int dimension, int coinPrct, int goombaPcrt, int koopaPrct, int mushPcrt, mt19937& rand){
    
    m_levelAry = new Element* [dimension * dimension];
    m_coins = coinPrct * dimension * dimension / 100;
    m_goombas = goombaPcrt * dimension * dimension / 100;
    m_koopas = koopaPrct * dimension * dimension / 100;
    m_mushrooms = mushPcrt * dimension * dimension / 100;
    m_dimension = dimension;

    Element **memLoc = m_levelAry;

    for (int i = 0; i < m_dimension; i++){
        for (int j = 0; j < m_dimension; j++){
            if (m_coins != 0){
                *(m_levelAry + i * m_dimension + j) = new Coin(i, j);
                m_coins--;
            } else if (m_mushrooms != 0){
                *(m_levelAry + i * m_dimension + j) = new Mushroom(i, j);
                m_mushrooms--;
            }else if(m_goombas != 0){
                *(m_levelAry + i * m_dimension + j) = new Goomba(i, j);
                m_goombas--;
            } else if (m_koopas != 0){
                *(m_levelAry + i * m_dimension + j) = new Koopa(i, j);
                m_koopas--;
            } else{
                *(m_levelAry + i * m_dimension + j) = new Nothing(i, j);
            }
            memLoc++;
        }
    }

    shuffle(m_levelAry, memLoc, rand);
}

Level::~Level(){
    delete[] m_levelAry;
}

int Level::getDimension(){
    return m_dimension;
}

void Level::repopulate(Element * elem, int row, int col){
    *(m_levelAry + row * m_dimension + col) = elem;
    elem->setCords(row,col);
}

Element* Level::getElement(int row, int col){
    return *(m_levelAry + row * m_dimension + col);
}

ostream &operator << (ostream &out, const Level &level){
    for (int i = 0; i < level.m_dimension; i++){
        for (int j = 0; j < level.m_dimension; j++){
            out << (**(level.m_levelAry + i * level.m_dimension + j)) << " ";
        }
        out << endl;
    }
    return out;
}

C++ i want to understand decimals [closed]

im trying to get a users int input in c++ and then from that input I am looking to show the decimal version of it, so for example the user enters 9281923, and then it shows 9.281923 as the answer. theres no limit to how many numbers a user can enter.

This is all i have so far:

 int main()
   {

      int num;
      cout << "Enter your number:" ;
      cin >> num;
   }

Any help is appreciate

Conditionally initialize class variable depending on the template type

Suppose I have the following code:

enum class Type
{
    Type32,
    Type64
};

template<Type T>
class MyClass
{
public:
    using MyType = typename std::conditional<T == Type::Type32, uint32_t, uint64_t>::type;
    
    MyType getSum()
    {
        MyType sum = 0;
        for(size_t i = 0;i < sizeof(arr);i ++)
        {
            sum += arr[i];
        }
        return sum;
    }

 private:
     //MyType arr[4] = { 0x1234, 0x5678, 0x9ABC, 0xDEF0 }; // for Type::Type32
     //MyType arr[2] = { 0x12345678, 0x9ABCDE }; // for Type::Type64
};

I try to initialize a class variable depends on the template type with the same name but different type and value. How can I do that? I probably looking for a solution that works in c++11.

How can I replace contains from C++20 in C++11 code? [closed]

I feel, like it's something easy, but I can't find an answer by myself.

auto iterator = _map.find(key);
DeliveryData smth;
if(/*check*/)
    smth = iterator->second;
return(smth);

How can I check for the result of find-method in this context? I know about contains in C++20. Any other method?

I forgot to say that find doesn't returns C++ expression of type bool or a type that can be converted to bool. It was not clear to me what should I use to compare with iterator.

Dev C++ [Error] undefined reference to and id returned 1 exit status

I'm new to this c++ and i'm working on a program using ostringstream to create string representations of the time in standard and universal time formats. But i keep getting some errors and will really apprectiate your help.

Time.h

#include <string>

#ifndef TIME_H
#define TIME_H

class Time{
    public:
        void setTime(int, int, int);
        std::string toUniversalString() const;
        std::string toStandardString() const;
    private:
        unsigned int hour{0};
        unsigned int minute{0};
        unsigned int second{0};
};

#endif

Time.cpp

#include <iomanip>
#include <stdexcept>
#include <sstream>
#include <string>
#include "Time.h"

using namespace std;

void Time::setTime(int h, int m, int s){
    if((h >= 0 && h < 24) && (m >= 0 && m < 60) && (s >= 0 && s < 60)){
        hour = h;
        minute = m;
        second = s;
    }
    else{
        throw invalid_argument("hour, minute and/or second was out of range");
    }
}

string Time::toUniversalString() const{
    ostringstream output;
    output << setfill('0') << setw(2) << hour << ":" << setw(2) << minute << ":" << setw(2) << second;
    return output.str();
}

string Time::toStandardString() const{
    ostringstream output;
    output << ((hour == 0 || hour == 12) ? 12 : hour % 12) << ":" << setfill('0') << setw(2) << minute << ":" << setw(2) << second << (hour < 12 ? " AM" : " PM");
    return output.str();
}

fig9.cpp

#include <iostream>
#include <stdexcept>
#include "Time.h"

using namespace std;

void displayTime(const string& message, const Time& time){
    cout << message << "\nUniversal time: " << time.toUniversalString() << "\nStandard time: " << time.toStandardString() << "\n\n";
}

int main(){
    Time t;
    
    displayTime("Initial time: ", t);
    t.setTime(13, 27, 6);
    displayTime("After setTime:  ", t);
    
    try{
        t.setTime(99, 99, 99);
    }
    catch(invalid_argument& e){
        cout << "Exception: " << e.what() << "\n\n";
    }
    
    displayTime("After attempting to set an invalid time:", t);
}

when i go to compile with my client program i get this error upon compilation

undefined reference to 'Time::toStandardString() const'
undefined reference to 'Time::toUniversalString() const'
undefined reference to 'Time::setTime(int,int,int)'
[Error] Id returned 1 exit status

Container that can iterate in order, access specific elements, and remove elements

I am currently using a std::vector<int> vec of size nto store the integers from 0 to n-1 in any order. Suppose that the vec is given by the following:

std::vector<int> vec = {4, 1, 2, 0, 3};

I need to

  • iterate over vec in order, i.e. 4 -> 1 -> 2 -> 0 -> 3.
  • access specific elements by index vec[3] -> 0.
  • remove specific elements by value del vec[2] -> {4, 1, 0, 3}.

The vector is given a priori and the maximum size is known (as we never add elements). What data structure would be suitable here (having performance in mind)?

mercredi 28 septembre 2022

How do I reinterpret a uint64_t variable bits as a double as opposed to static_cast?

uint64 value = 0x543;
double dval = *reinterpret_cast<double*>(&value);

Is there any danger doing this? Do you see a more efficient way of doing this?

Thanks

how to connect socket.io server using socket.io client cpp

I'm trying to connect to the socket.io server that is using parser. The following code connects well to server.

export const connect_push_socket = createAction(CONNECT_SOCKET, () => {
    const socket = io.connect(process.env.NEXT_PUBLIC_WEBSOCKET_URL, {
        reconnection: false,
        withCredentials: true,
        parser: socketIoMsgpackParser
    });

    return {
        socket: socket
    }
});

But when I try to implement that in C++, the connection is immediately lost.

sio::client h;
connection_listener l(h);

h.set_open_listener(std::bind(&connection_listener::on_connected, &l));
h.set_close_listener(std::bind(&connection_listener::on_close, &l,std::placeholders::_1));
h.set_fail_listener(std::bind(&connection_listener::on_fail, &l));

h.connect("wss://gateway.abc.com");
_lock.lock();
if (!connect_finish)
{
cout << "wait\n";
    _cond.wait(_lock);
}

_lock.unlock();
current_socket = h.socket();
h.sync_close();
h.clear_con_listeners();

error code :

[2022-09-28 23:02:26] [devel] endpoint constructor
[2022-09-28 23:02:26] [devel] client constructor
wait
[2022-09-28 23:02:26] [connect] Successful connection
[2022-09-28 23:02:26] [connect] WebSocket Connection 111.67.154.150:443 v-2 "WebSocket++/0.8.2" /socket.io/?EIO=4&transport=websocket&t=1664373746 101
Connected.
encoded payload length:2
Close by reason:End by user
[2022-09-28 23:02:26] [warning] got non-close frame while closing
[2022-09-28 23:02:27] [error] handle_read_frame error: asio.ssl.stream:1 (stream truncated)
[2022-09-28 23:02:27] [info] asio async_shutdown error: asio.ssl.stream:1 (stream truncated)
[2022-09-28 23:02:27] [devel] handle_terminate error: asio.ssl.stream:1 (stream truncated)
Client Disconnected.
clear timers
sio closed

couldn't infer template argument - do I need to use explicit template parameters?

template <int I, typename T> struct Wrap {
  T internal;
};

template <int I, typename T>
Wrap<I, T> DoStuff(int z) { return Wrap<I, T>{(T)z}; }

class Wrapped {
public:
// Working
  Wrap<1, int> GetInt() { return DoStuff<1, int>(1); }
  Wrap<2, long> GetLong() { return DoStuff<2, long>(2); }

// Not working
  Wrap<3, char> GetChar() { return DoStuff(3); }
};

Try it online

Why is the third function failing to resolve the template argument? I thought the compiler would try to match the template definition with the return type of the function. Is this working in c++14 or any newer versions?

C++ Simplify loop over map and extending/overwriting of vector

Given

  • std::vector<int> vec1 of size s_vec and capacity c.
  • std::vector<int> vec2.
  • std::map<int, int> m of size s_m >= s_vec.
  • std::unordered_set<int> flags.
  • bool flag = False

I want to copy as many values of m (in order) into vec1 (overwriting previous values) without exceeding the capacity c. If any values remain I want to push those values to the end of vec2. For each of these, values I want to check if they are in flags. If they are, I'd like to set flag to true.

This is how I currently, achieve this:

  int i = 0;
  for (auto const& e : m) {
    if(i < c) {
      if(i == vec1.size()) {
        vec1.push_back(e.second);
      } else {
        vec1.at(i) = e.second;
      }
    } else {
      vec2.push_back(e.second);
      if(flags.count(e.second)){
        flag = true;
      }
    }
  }

I am new to C++ coming from python and R. Therefore, I assume that this can be simplified quite a bit (with iterators?). What can I do to improve the code here?

How to get std::bind refer the explicit constructor defined in class while providing pointer to class member function as arguement?

I'm using std::bind in my code as shown below:

std::bind(&Filter::odometryCallback, filter, std::placeholders::_1, odomTopicName, poseCallbackData,
                   twistCallbackData);

The Filter class has explicit constructors defined and hence no default constructors are generated by the compiler (for this class).

Now, the above line of code throws error with message "use of deleted function" and mentioning the copy constructor of Filter class.

My requirement:

How to get &Filter::odometryCallback to be considered/evaluated as pointer of explicitly constructed class instance member function ?

Any solutions and detailed explanation would be helpful.

Repeatedly non-stop output when I input char into int variable

The folowing code tells user to input their age, the set to be input interger between 0 and 120, it is capable to deal with wrong input like 'M' or 133 or -1. Warning message goes like this:Warning message

case 1:                                // input age
        cout << "Enter your age: ";
        cin >>  age;
        
        if(age <= 0 || age > 120){     // if the input type or number was wrong, it goes here
            while(1){                
                cout << "Invalid input! Please enter again" << endl << ">>>";
                age = -1;
                cin >> age;
                if(age > 0 && age <= 120) {break;}
            }
        }

However, it'll go wrong if I input something like \ or [. Repeating Warning message

How can I solve this?

mardi 27 septembre 2022

create a shopping cart in c

Taking into account the following menu make a script that allows to read some option of the menu and read the number of portions of each food and calculate the total count. The program should ask if you want to add another food.

I need my program after selecting a product and quantity to show me my subtotal and ask me if I want to add more items, if the answer is yes, go back to the item menu and after selecting item and quantity give me again my subtotal of the 2 products, and if the answer is no, give me my total.

I don't know how to make it ask me if I want to add a product and go back to the menu to select a product and keep saving and incrementing the cart total.

#include <iostream>
#include <cstdlib>

using namespace std;

void Cabeza();
void Bistec();
void Lengua();
void Pastor();
void Refrescos();
void Total();

int main()
{
    int opcion;
    bool repetir = true;

    do
    {
        system("cls");

        cout << "\n\n\t\t\tTacos doña lupe" << endl;
        cout << "\t\t\t----------------" << endl;
        cout << "\n\t1. Tacos de Cabeza-----$8.0 c/u" << endl;
        cout << "\t2. Tacos de Bistec-----$8.5 c/u" << endl;
        cout << "\t3. Tacos de Lengua-----$10.0 c/u" << endl;
        cout << "\t4. Tacos al Pastor-----$7.5 c/u" << endl;
        cout << "\t5. Refrescos-----$14.0 c/u" << endl;
        cout << "\t0. SALIR" << endl;

        cout << "\n\tDe que los va a querer? ";
        cin >> opcion;

        int numero;
        float subtotal;
        switch (opcion)
        {
        case 1:
            Cabeza();
            break;

        case 2:
            Bistec();
            break;

        case 3:
            Lengua();
            break;

        case 4:
            Pastor();
            break;

        case 5:
            Refrescos();
            break;

        case 0:
            repetir = false;
            break;
        }
    } while (repetir);

    return 0;
}

void Cabeza()
{
    int numero;
    float subtotal;

    cout << "\n\tCuantos vas a querer? ";
    cin >> numero;

    subtotal = numero * 8;
    cout << "\tsubtotal: " << subtotal << endl;

    system("pause>nul");
}

void Bistec()
{
    int numero;
    float subtotal;

    cout << "\n\tCuantos vas a querer? ";
    cin >> numero;

    subtotal = numero * 8.5;
    cout << "\tsubtotal: " << subtotal << endl;

    system("pause>nul");
}

void Lengua()
{
    int numero;
    float subtotal;

    cout << "\n\tCuantos vas a querer?";
    cin >> numero;

    subtotal = numero * 10;
    cout << "\tsubtotal: " << subtotal << endl;

    system("pause>nul");
}

void Pastor()
{
    int numero;
    float subtotal;

    cout << "\n\tCuantos vas a querer? ";
    cin >> numero;

        subtotal = numero * 7.5;
        cout << "\tsubtotal: " << subtotal << endl;

    system("pause>nul");
}

void Refrescos()
{
    int numero;
    float subtotal;

    cout << "\n\tCuantos vas a querer?";
    cin >> numero;

    subtotal = numero * 14;
    cout << "\tsubtotal: " << subtotal << endl;

    system("pause>nul");
}

Can't install the Vulkan SDK from tarball on Fedora Linux

I tried to install the Vulkan SDK from the tarball from the LunarG website (version 1.3.224.1) on Fedora 37 beta (I also tried it on Nobara Linux 36) and kept getting these errors.

In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = Json::Value::ValueHolder]’,
    inlined from ‘void Json::Value::swapPayload(Json::Value&)’ at /home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:2967:12,
    inlined from ‘bool Json::Reader::readValue()’ at /home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:433:31:
/usr/include/c++/12/bits/move.h:205:7: error: ‘v.Json::Value::value_’ may be used uninitialized [-Werror=maybe-uninitialized]
  205 |       __a = _GLIBCXX_MOVE(__b);
      |       ^~~
/home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp: In member function ‘bool Json::Reader::readValue()’:
/home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:432:11: note: ‘v’ declared here
  432 |     Value v;
      |           ^
In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = Json::Value::ValueHolder]’,
    inlined from ‘void Json::Value::swapPayload(Json::Value&)’ at /home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:2967:12,
    inlined from ‘bool Json::Reader::readValue()’ at /home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:446:33:
/usr/include/c++/12/bits/move.h:205:7: error: ‘v.Json::Value::value_’ may be used uninitialized [-Werror=maybe-uninitialized]
  205 |       __a = _GLIBCXX_MOVE(__b);
      |       ^~~
/home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp: In member function ‘bool Json::Reader::readValue()’:
/home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:445:13: note: ‘v’ declared here
  445 |       Value v;
      |             ^
In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = Json::Value::ValueHolder]’,
    inlined from ‘void Json::Value::swapPayload(Json::Value&)’ at /home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:2967:12,
    inlined from ‘bool Json::OurReader::readValue()’ at /home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:1355:31:
/usr/include/c++/12/bits/move.h:205:7: error: ‘v.Json::Value::value_’ may be used uninitialized [-Werror=maybe-uninitialized]
  205 |       __a = _GLIBCXX_MOVE(__b);
      |       ^~~
/home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp: In member function ‘bool Json::OurReader::readValue()’:
/home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:1354:11: note: ‘v’ declared here
 1354 |     Value v;
      |           ^
In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = Json::Value::ValueHolder]’,
    inlined from ‘void Json::Value::swapPayload(Json::Value&)’ at /home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:2967:12,
    inlined from ‘bool Json::OurReader::readValue()’ at /home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:1392:33:
/usr/include/c++/12/bits/move.h:205:7: error: ‘v.Json::Value::value_’ may be used uninitialized [-Werror=maybe-uninitialized]
  205 |       __a = _GLIBCXX_MOVE(__b);
      |       ^~~
/home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp: In member function ‘bool Json::OurReader::readValue()’:
/home/said/vulkan/1.3.224.1/source/VulkanTools/submodules/jsoncpp/dist/jsoncpp.cpp:1391:13: note: ‘v’ declared here
 1391 |       Value v;
      |             ^

I tried going through the CMake files to try to disable the -Werror=maybe-uninitialized option but I'm not familiar with CMake so couldn't find a way to do that. I also tried going through the C++ source code itself and trying to fix it that way but still could not fix the issue.

Thank you very much.

How outdated is C++11 [closed]

Hey so I have had pretty basic experience with programming doing a little bit of Java and C here and there but I really want to dive deep into C++ and learn it really well. While looking through resources to learn the language, everyone suggested reading C++ Primer. I was reading it and found out the the 5th version only goes up to C++11. As someone who is new to C++ in 2022, would it hurt me down the line to learn an older language like this through C++ primer or would it be fine to continue reading the book and just make adjustments later on? And if I should learn a newer version, which version do you recommend I learn?

Can Webassembly Module be serialized?

Is it possible to serialize a WebAssembly module ? Like this. I find out that it is implemented here . But I didn't got the full implementation of it.

lundi 26 septembre 2022

Making a BST from a sorted array

I am having issues building out a bst function that takes in a pointer to an array and a size. I believe I have it mostly figured out, until I build out the right subtree. The pseudo goes: check if it's done when size is zero, otherwise, find the middle point of the array, and insert that value. Then that roots left will be finding the middle of the array to the left of roots value and right will find the middle of the array to the right of roots value and repeat recursively until the arrays have been broken down enough that they have no size. Here is what I have so far.

template <typename T> // sorted array -> tree
tree_node<T>* tree_from_sorted_list(const T* a, int size){
    if (size == 0){
        return nullptr;
    }
    
    int mid = size/2;
    tree_node<T>* root = nullptr;
    
    tree_insert(root, a[mid]);

    root->_left = tree_from_sorted_list(a, mid-1);
    root->_right = tree_from_sorted_list();

    return root;
}

I can't figure out how to implement root->_right. Ive been told the solution would be (a, a+index+1) but I am not sure what that means. How would this be converted to an int so that the recursive call then gets that array from to the right of the value that is being inserted?

How std::move works in improving performance?

I am learning std::move.

I think this keyword can avoid copy in real code, to improve performance.

but when i write the demo code:

#include <bits/stdc++.h>
#include "util/time_util.h"
using namespace std;

int main() {
  util::time_util::Timer t;
  t.StartTimer();
  std::vector<std::string> a;
  for (size_t i = 0; i < 1e7; ++i) {
    std::string s = "asd";
    // a.push_back(std::move(s));  // this is a right value, can avoid copy, i think
    a.push_back(s);  // this is a left value, will copy
  }
  t.EndTimer("cost");
}

As above shows, i test two kind of push_back, one is push_back left value, one is push_back std::move.

but i found the cost time is same(I dont use any compiler optimization).

could you help on this, and could you list a demo code, when std::move will improve performance significantly?

Passing a temporary stream object to a lambda function as part of an extraction expression

I have a function which needs to parse some arguments and several if clauses inside it need to perform similar actions. In order to reduce typing and help keep the code readable, I thought I'd use a lambda to encapsulate the recurring actions, but I'm having trouble finding sufficient info to determine whether I'm mistakenly invoking undefined behavior or what I need to do to actualize my approach.

Below is a simplified code snippet of what I have currently:

int foo(int argc, char* argv[])
{
    Using ss = std::istringstream;

    auto sf = [&](ss&& stream) -> ss& {
        stream.exceptions(ss::failbit);
        return stream;
    };

    int retVal = 0;

    bool valA = false;
    bool valB = false;

    try
    {
        for(int i=1; i < argc; i++)
        {
            std::string arg( argv[i] );

            if( !valA )
            {
                valA = true;
                sf( ss(arg) ) >> myInt;
            }
            else
            if( !valB )
            {
                valB = true;
                sf( ss(arg) ) >> std::hex >> myOtherInt;
            }
        }
    }
    catch( std::exception& )
    {
        retVal = -1;
        std::cerr << err.what() << std::endl;
    }
    
    return retVal;
}

First, based on what I've read, I don't think that specifying the lambda argument as an rvalue reference (ss&&) is doing quite what I want it to do, however, trying to compile with it declared as a normal reference (ss&) failed with the error cannot bind non-const lvalue reference of type 'ss&'. Changing ss& to ss&& got rid of the error and did not produce any warnings, but I'm not convinced that I'm using that construct correctly.

I've tried reading up on the various definitions for each, but the wording is a bit confusing.

I guees my ultimate questions are:

  1. Can I expect the lifetime of my temporary ss(arg) object to extend through the entire extraction expression?

  2. What is the correct way to define a lambda such that I can use the lambda in the way I demonstrate above, assuming that such a thing is actually possible?

Undefined symbols for architecture arm64 in template function with packed parameters [duplicate]

I have a template function that takes a variable amount of parameters (packed parameters):

// func.cpp
template<typename ...T>
void func(const std::string& arg, T... args) {
    // ...
}

and its header file looks like this:

// func.h
#pragma once
#ifndef PROJECTNAME_FUNC_H
#define PROJECTNAME_FUNC_H

#include <string>

template<typename ...T>
void func(const std::string& arg, std::string args...);

#endif //PROJECTNAME_FUNC_H

And finally, my main function looks like this:

// main.cpp
#include <string>
#include "func.h"

int main() {
  func("foo", "bar", "baz", "qux");
  return 0;
}

If I try to build my program using g++ -std=c++11 ./*.cpp I get the following error:

Undefined symbols for architecture arm64:
  "void func<>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, ...)", referenced from:
      _main in main-48d32c.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

If I move the definition of func to main.cpp it works fine, so I'm assuming I'm doing something wrong in func.h, but I couldn't figure out what. I've tried using explicit instantiation of the template function as well but with no success.

My CMakeLists.txt file only has the basic commands, generated by CLion when the project was created. I've double-checked and the add_executable(<projectname> file.cpp ...) contains all the source code and header files. If it's relevant to my problem, I can provide it as well.

Template resolution with template template parameter

I'm trying to implement a "decoder" which can treat input data differently depending on the expected return type.

The following code seemed to work in https://cppinsights.io/:

#include <cstring>
#include <vector>

template<template <class, class> class V, typename T> void Bar(V<T, std::allocator<T>> &v, char** c) {
    size_t s = *(size_t*)*c;
    v.resize(s);
    memcpy((char*)&v[0], *c, s * sizeof(T));
}

template<typename T> inline void Bar(T &t, char** c) { t = *(T*)*c; }

template<typename T> T Foo(char** c) { T t; Bar<T>(t, c); return t; }

char bob[] = {8,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,9,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0};
char boz[] = {5,0,0,0};

int baz = Foo<int>((char **)&boz);
std::vector<int> bub = Foo<std::vector<int>>((char **)&bob);

So I thought that the final call to Foo would use the first definition of Bar but this is not happening, if I delete the second definition of Bar, the following code does not compile:

#include <cstring>
#include <vector>

template<template <class, class> class V, typename T>
void Bar(V<T, std::allocator<T>> &v, char** c) {
  size_t s = *(size_t*)*c;
  v.resize(s);
  memcpy((char*)&v[0], *c, s * sizeof(T));
}

template<typename T>
T Foo(char** c) { T t; Bar<T>(t, c); return t; }

char bob[] = {8,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,9,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0};

std::vector<int> bub = Foo<std::vector<int>>((char **)&bob);

and I get the following error message:

error: no matching function for call to 'Bar' 
template<typename T> T Foo(char** c) { T t; Bar<T>(t, c); return t; }
                                            ^~~~~~
note: in instantiation of function template specialization 'Foo<std::vector<int>>' requested here
std::vector<int> bub = Foo<std::vector<int>>((char **)&bob);
                       ^
note: candidate template ignored: invalid explicitly-specified argument for template parameter 'V'
template<template <class, class> class V, typename T> void Bar(V<T, std::allocator<T>> &v, char** c) {
                                                           ^

I can't really understand what it means, why is the compiler not using the definition with the "template template" parameter? I have similar functions for "encoding" the data and it works, what am I doing wrong?

Am I trying to solve the wrong problem? How can I "split" the decoding function depending on the expected return type, while keeping it generic (or at least have a different handling of vector vs non-vector types)? Thanks.

dimanche 25 septembre 2022

How am I using the formula wrong? (calculating PI with nested square roots)

I want to calculate the approx of pi with Viete's formula of nested square roots of 2

#include <iostream>
#include <iomanip>
#include <cmath>

using namespace std;
int main()
{
    int k; //variable for user input
    int n = 1; //built integer that causes the program to loop
    double result;
    //greeting message, start of program
    cout << "Welcome to the Approx PI program.\n";
    cout << "Please enter in a value for k...\n";
    cin >> k;
    //if user inputs a number outside the interval
    while (k < 1 || k > 30)
    {
        cout << "Invalid ---k must be >=1 and <=30\n";
        cout << "Please enter in a value for k...\n";
        cin >> k;
    }
    //calculating PI with the nested square root formula
    while (n <= k - 1)
    {
        result = sqrt(2 + result);
        n++;
    }
    result = pow(2, k) * sqrt(2 - result);
    //outputs the result, end of program
    cout << "Approx PI =         " <<setprecision(20)<<fixed<<result<<endl;
    return 0;
}

But when I enter 28, it gives me 4:

Welcome to the Approx PI program.
Please enter in a value for k...
28
Approx PI =         4

Process finished with exit code 0

When I enter 29 or 30, the result is 0:

Welcome to the Approx PI program.
Please enter in a value for k...
30
Approx PI =         0

Process finished with exit code 0

I think k=30 should be giving me:

Approx PI = 3.14245127249413367895

What am I doing wrong?

std::move with a function that expects an rvalue reference [duplicate]

I've been doing some examples based around move semantics and I stumbled upon a case that I'm unable to explain and I wasn't able to find a similar question here on stackoverflow either. I suppose there's something obvious that I am not aware of or it's my lack of understanding of the issue as a whole so bear with me.

Let's suppose we have a function:

void func(std::vector<std::string>&& vec)
{
    cout << "Passed vector has " << vec.size() << " elements" << endl;
}

And later some vector is being passed as an argument to it through std::move (that is, basically casting it, I realize that):

std::vector<std::string> v(100);

std::cout << "Before calling the function, vector has " << v.size() << " elements" << std::endl;
func(std::move(v));
std::cout << "After calling the function, vector has " << v.size() << " elements" << std::endl;

It this case, I'm getting the following output (and the elements are still present in the v, at least that's my conclusion upon looking it up under debugger):

Before calling the function, vector has 100 elements
Passed vector has 100 elements
After calling the function, vector has 100 elements

If I change the function and get rid of the rvalue reference, I'm getting the expected result (at least expected to my understanding of move semantics...):

Before calling the function, vector has 100 elements
Passed vector has 100 elements
After calling the function, vector has 0 elements

What am I missing?

samedi 24 septembre 2022

Regex matches the string that is the part of an explicit string

Regex matches the string that is the part of an explicit string.

e.g.

an explict string

hello world!

matches

h
he
...
hello wor
hello worl
hello world!

not matches

a
ah
ha
hallo
hbbbo asrld!
hbbboaasrld!
Thbbboaasrld!

As shown below

/^h(e(l(l(o( (w(o(r(l(d(!?)?)?)?)?)?)?)?)?)?)?)?$/

but it is not convenient for modification and expansion.

Is there a simpler expression?

How could you write a loop to compute sqrt(2 + sqrt ( 2+ (sqrt ( 2 +...) n times

//The n is input as an integer between 1 and 30.I have no idea where to start for the sqrt function. We are asked to only use input/output statements, variables, selection statements, and loops. Using functions or arrays is not allowed because we haven't learned them so far. So far I have this: This makes sure the user enters a valid integer but I don't know where to go from here.

using namespace std;
int kvalue;

int main() {
 cout << "Welcome to the Approx PI program.\n";
 cout << "Please enter in a value for k...";
 cin >> kvalue;


 // validate the input of the user
 while (kvalue<1 || kvalue>30)
 {
     cout << "Please enter a valid k value...";
     cin >> kvalue;

 }

vendredi 23 septembre 2022

How do I fix an invalid write using the vector library?

I'm working on an assignment, and I'm running into an error where I run my code I get "malloc(): invalid size (unsorted) aborted (core dumped)". Using Valgrind, I can see that the error is an "Invalid write of size 8" happening when I am calling emplace_back() but I have no idea why it is causing this issue. There is much more code than this, but I've tried to include only what I think is relevant to the issue.

std::vector<REG::REG_node *> my_LexicalAnalyzer::matchOneChar(std::vector<REG::REG_node *> S, char c)
{
    std::vector<REG::REG_node *> s1;
    for (int i = 0; i < S.size(); i++)
    {
        if (S[i]->first_label == c && !contains(s1, S[i]->first_neighbor))
            s1.emplace_back(S[i]->first_neighbor);
        if (S[i]->second_label == c && !contains(s1, S[i]->second_neighbor))
            s1.emplace_back(S[i]->second_neighbor);
    }

    if (s1.empty())
        return s1;

    bool changed = true;
    std::vector<REG::REG_node *> s2;

    while (changed)
    {
        changed = false;

        for (int i = 0; i < s1.size(); i++)
        {
            s2.push_back(s1[i]);

            if (s1[i]->first_label == '_' && !contains(s2, s1[i]->first_neighbor))
                s2.push_back(s1[i]->first_neighbor);
            if (s1[i]->second_label == '_' && !contains(s2, s1[i]->second_neighbor))
                s2.push_back(s1[i]->second_neighbor);
        }

        if (s1 != s2)
        {
            changed = true;
            std::vector<REG::REG_node *> empty;

            // Copy s2 into s1 and empty into s2
            copy(s2.begin(), s2.end(), s1.begin());
            copy(empty.begin(), empty.end(), s2.begin());
        }
    }

    return s1;
}
class REG
{
public:
    struct REG_node
    {
        struct REG_node *first_neighbor;
        char first_label;
        struct REG_node *second_neighbor;
        char second_label;
    };
};

This is where the nodes are being allocated.

REG::REG_graph *REG::createREG(char input)
{
    struct REG_node *node1 = new REG_node{nullptr, input, nullptr, '\0'};
    struct REG_node *node2 = new REG_node{nullptr, '\0', nullptr, '\0'};

    node1->first_neighbor = node2;

    struct REG_graph *graph = new REG_graph{node1, node2};
    return graph;
}

std::list doesn't initialize correctly after it's content gets read from fstream

To explain briefly: Using <fstream>, I write a std::list instance to a .txt file:

#include <fstream>
#include <list>

std::list<Item> list_1; //example list
list_1.push_back(Item(...));

std::ofstream file;
file.open("record.txt", std::ios::trunc);

if (file.is_open()) {
    file.write((char*)&list_1, sizeof(std::list<Item>)) << std::endl;

    file.close();
}

However, when I read from the same file and assign the data to a std::list instance:

file.open("record.txt", std::ios::in);
if (file.is_open()) {
    std::list<Item> list_1;
    file.read((char*)&list_1, sizeof(std::list<Item>));
}

It gives me an error when I try to access its elements. This is, however, not my problem. Because std::list stores the pointer to that element, I must store the elements manually, like I did here:

for (auto const& item : list_1) {
    file << item.amount << std::endl;
    file << item.value << std::endl;
    file << item.item_name << std::endl;
    file << (char*)&item.type << std::endl;
}

Then I read these values. Use the values to create a new Item instance and store it inside my list. Side note: I can access the size() property of the list_1 from the .txt file because it is a member of std::list<Item> which lives on the stack. So it gets saved by the ofstream.

for (int i = 0; i < list_1.size(); i++) {
    int amount = 0;
    int value = 0;
    std::string item_name;
    Item_Type type = item;

    file >> amount;
    file >> value;
    file >> item_name;
    file >> (char*)&type;

    Item item(amount, value, item_name, type);
    main_player_inv.push_back(item);

I expect this to work, because now the std::list should have no uninitialized members, right?

Well, it gives me this error:

this->_Mypair._Myval2._Myhead was 0x228B4050240

This basically means list_1->_Mypair._Myval2._Myhead is a pointer which points to memory out of bounds. The problem is, unlike the element pointers which I can manually save the values of and initialize, I can't access the data of list_1->_Mypair._Myval2._Myhead or edit it manually, as it is a private member. Or, there isn't a way I could find online.

So, I have two questions:

  • Can I initialize list_1->_Mypair._Myval2._Myhead so that it points to a valid memory?

  • Is there a way to more easily serialize a std::list and retrieve it's content?

If both of these questions are unanswerable, I would like to talk about what I'm trying to do:

The std::list<Item> is used as a character or an object's inventory. In my project, I want to store the items the player and objects such as containers have in a std::list<Item> instance. I thought this was the most fitting thing to do for an object-oriented Player structure. Here are some classes, for example:

Player class

class Player : public Object {
public:
    int level, experience;
    double health;
    float resistance; // 0.000 - 1.000
    std::list<Item> inventory;
public:
    Player() :
        level(0), experience(0), health(10.0), resistance(0.0f) {};
    Player(int x, int y, std::string obj_name, Obj_Type type, int level, int experience, double health, float resistence) :
        Object(x, y, obj_name, type), level(level), experience(experience), health(health), resistance(resistence) {};
};

Item class

struct Item {
public:
    unsigned int amount, value;
    std::string item_name;
    Item_Type type;  // enum
public:
    Item() :
        amount(0), value(0), item_name("undefined"), type(item) {};
    Item(int amount, int value, std::string item_name, Item_Type type) :
        amount(amount), value(value), item_name(item_name), type(type) {};
};

If you know a better way to store player items, items being class instances; or know altogether a better way to do this, please help me.

How to write a thread-save singliton using C++11

I'm not sure does this is thread-safe:

#include <thread>
#include <stdio.h>

class A {
public:
  static A* instance() {
      static A* ptr = new A();
      return ptr;
  }

  int val_;
};

int main(int argc, char *argv[]) {
  auto ptr = A::instance();
  printf("thread value: %d\n", ptr->val_);
  //thd1.join();
  return 0;
}

The C++ code and ARM assembly: https://godbolt.org/z/aPYarcoM9

I've understand that the guard variable ensure the static variable initialized once only, and the guard aquire/release lock the construction of class A.

What I not sure is the following is thread-safe?

auto ptr = A::instance();

jeudi 22 septembre 2022

Uniform Resource Identifier (URI)

A Uniform Resource Identifier (URI) is a string of characters which identifies an Internet Resource.

The most common URI is the Uniform Resource Locator (URL) which identifies an Internet domain address. Another, not so common type of URI is the Universal Resource Name (URN).

In C++, which Standard Library functions (if any) are required to implicitly provided an atomic memory fence?

For example, is calling std::mutex::lock() required by the Standard to provide a sequentially consistent fence, an acquire fence, or neither?

cppreference.com doesn't seem to address this topic. Is it addressed in any reference documentation that's more easy to use than the Standard or working papers?

error C2312 is thrown for ifstream::failure and ofstream::failure exceptions

I am writing a small application that modifies a text file. It first creates a copy of the file in case something goes wrong.

The following function creates this copy in the same directory. It takes the file's name as an argument and returns true if the copy is successfully created, and false if it fails.

#include <iostream>
#include <filesystem>
#include <fstream>
#include <string>

using std::ifstream;
using std::ofstream;
using std::string;
using std::cerr;
using std::cin;
using std::cout;
using std::endl;

bool backupFile(string FileName) {
    cout << "Creating backup for " << FileName << "..." << endl;

    try { // for debugging purposes
        string NewName = "bkp_" + FileName;
        string CurLine;
        ifstream FileCopy(FileName);
        ofstream FileBackup(NewName);

        if (FileCopy.fail()) { // Could specify how file copy failed?
            cerr << "Error opening file " << FileName << ".";
            return false;
        }
        
        while (getline(FileCopy, CurLine)) { // Copy lines to new file
            //cout << "Copying " << CurLine << "\" to " << NewName << "." << endl;
            FileBackup << CurLine << "\n";
        }     


        cout << "File successfully backed up to " << NewName << endl;
        return true;
    }
    catch (const ifstream::failure& iE) {
        cerr << "Exception thrown opening original file: " << iE.what() << endl;
        return false;
    }
    catch (const ofstream::failure& oE) {
        cerr << "Exception thrown outputting copy: " << oE.what() << endl;
    }
    catch (...) {
        cerr << "Unknown exception thrown copying file." << endl;
        return false;
    }
}

I've used a few catch statements to indicate if there is an issue with the input (ifstream::failure), the output (ofstream::failure), or neither.

During compilation, however, the following error appears:

error C2312: 'const std::ios_base::failure &': is caught by 'const std::ios_base::failure &' on line 42

To me, the error implies that both ifstream::failure and ofstream::failure are caught on ifstream::failure, which seems strange. When I remove the catch for ofstream::failure, it runs fine.

Why is this the case?

Convert enum values from external library to local datatypes

I have lot of enum from external library, which I am trying to convert it to local datatypes. I do not want datatypes or header files from external library to be included everywhere in the client code.

At present I am doing something like below. Is there a better way to do this.

struct ExtServer {
  enum class Color { RED, BLACK, GREEN, ORANGE };
  enum class Fruit { ORANGE, APPLE };
};

struct Wrapper {
  enum class Color { RED, BLACK, GREEN, ORANGE };
  enum class Fruit { ORANGE, APPLE };
  
  template<typename T, typename U> 
  T convert(U value) { return static_cast<T>(value); }
  
  Color From(ExtServer::Color color) {
    return convert<Color, decltype(color)>(color);
  }
  Fruit From(ExtServer::Fruit fruit) {
    return convert<Fruit, decltype(fruit)>(fruit);
  }
};

struct Client {
  void do_something() {
    Wrapper obj;
    obj.From(ExtServer::Color::RED);
    obj.From(ExtServer::Fruit::APPLE);
  }
};
  
int main() {
    Client client;
    client.do_something();
}

Is there a way to expect global exception in GTest?

I have a scenario where a call SendFeedback() sends a message and returns successfully. The message is received by another thread which throws. EXPECT_THROW doesn't work because SendFeedback() does not throw itself. Is there a way to expect this kind of exceptions?

pseudo-code:

auto listener = Listener();
auto sender = Sender();
...
sender.SendFeedback();

// listener throws due to unexpected feedback. This exception is to be expected

mercredi 21 septembre 2022

Converting init-statements to earlier c++ compiler

I found a function that I would like to steal and add to my project. The only problem is that I keep getting the error that it is only c++17 compatible which does not work for my current project.

Here is the code:

  std::string JoinVectorByStringA(const std::vector<std::string>& v, const std::string& delimiter)
{
    std::string out;
    if (auto i = v.begin(), e = v.end(); i != e)
    {
        out += *i++;
        for (; i != e; ++i)
        {
            out.append(delimiter).append(*i);
        }
    }
    return out;
}

I have tried various approaches but they have added more errors. I am using MSVC 2019 (v142). Does anyone know how to make this compatible?

Thank you.

c++20 and c++11 standards both specified in tasks.json, still won't work?

I'm learning C++ using Visual Studio Code. I'm starting to pull my hair out trying to figure why the compiler won't recognize C++11 standards. The code + .json file + error are as follows:

#include <iostream>
#include <vector>
using namespace std;

int main() {

    vector <int> vector_numbers;

    for (int i : vector_numbers) {
        vector_numbers[1] = i + 1;
    }

    for (int i : vector_numbers) {
        cout << "The vector element at index [" << i << "] is " << vector_numbers.at(i) << endl;
    }

    return 0;
}

The contents of "args" parameter in tasks.json is

            "args": [
                "-std=c++11",
                "-std=c++17",
                "-std=c++20",
                "-stdlib=libc++",
                "-fcolor-diagnostics",
                "-fansi-escape-codes",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ]

and error is:

<REDACTED> % cd "<REDACTED PATH>" && g++ Vectors.cpp -o Vectors && "<REDACTED PATH>"Vectors
Vectors.cpp:9:16: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
    for (int i : vector_numbers) {
               ^
Vectors.cpp:13:16: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
    for (int i : vector_numbers) {
               ^
2 warnings generated.

lifetime of function local variable and temporary object

I'm getting the different behaviour on different compliler, on GCC temporary object and local variable are destroyed in the end of an expression but on MSVC compiler, local variable and temporary object are destroyed at the end of function. why i'm getting this different behaviour ? see live demo

struct X{ 
    X() 
    {
        std::cout << "X::X() " << '\n';
    }

    X(const X& arg)
    {
        std::cout << "X::Copy" << '\n';
    }

    X(X&& arg)
    {
        std::cout << "C::move" << '\n';
    }
        
    ~X(){ std::cout << "Goodbye, cruel world!\n"; }

};
X  f(X  x){
    X arg{};
    std::cout << "Inside f()\n";
    return x;
}
void g(X  x){
    std::cout << "Inside g()\n";
}

int main()
{
    X arg{};
    g(f(arg));
}

GCC output:

X::X() 
X::Copy
X::X() 
Inside f()
C::move
Goodbye, cruel world!
Inside g()
Goodbye, cruel world!
Goodbye, cruel world!
Goodbye, cruel world!

MSCV output:

X::X() 
X::Copy
X::X() 
Inside f()
C::move
Goodbye, cruel world!
Goodbye, cruel world!
Inside g()
Goodbye, cruel world!
Goodbye, cruel world!

Need help understanding why this invalid C++ code compiles successfully

The following code compile correctly for me in some environments (e.g. on compiler explorer with gcc 9.3.0) and complains in others (CentOS 7.9.2009 (Core), gcc 9.3.1).

#include <iostream>
using namespace std;

int main() {
    std::string name="aakash";
    name.erase(name.begin()+2, name.cend());
    return 0;
}

When I get an error, the error is :

test.cpp:6:40: error: no matching function for call to 'std::basic_string<char>::erase(__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, std::basic_string<char>::const_iterator)'
    6 |  name.erase(name.begin()+2, name.cend());
      |                                        ^
In file included from /opt/rh/devtoolset-9/root/usr/include/c++/9/string:55,
                 from /opt/rh/devtoolset-9/root/usr/include/c++/9/bits/locale_classes.h:40,
                 from /opt/rh/devtoolset-9/root/usr/include/c++/9/bits/ios_base.h:41,
                 from /opt/rh/devtoolset-9/root/usr/include/c++/9/ios:42,
                 from /opt/rh/devtoolset-9/root/usr/include/c++/9/ostream:38,
                 from /opt/rh/devtoolset-9/root/usr/include/c++/9/iostream:39,
                 from test.cpp:1:
/opt/rh/devtoolset-9/root/usr/include/c++/9/bits/basic_string.h:4698:7: note: candidate: 'std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::erase(std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]'
 4698 |       erase(size_type __pos = 0, size_type __n = npos)
      |       ^~~~~
/opt/rh/devtoolset-9/root/usr/include/c++/9/bits/basic_string.h:4698:23: note:   no known conversion for argument 1 from '__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >' to 'std::basic_string<char>::size_type' {aka 'long unsigned int'}
 4698 |       erase(size_type __pos = 0, size_type __n = npos)
      |             ~~~~~~~~~~^~~~~~~~~
/opt/rh/devtoolset-9/root/usr/include/c++/9/bits/basic_string.h:4714:7: note: candidate: 'std::basic_string<_CharT, _Traits, _Alloc>::iterator std::basic_string<_CharT, _Traits, _Alloc>::erase(std::basic_string<_CharT, _Traits, _Alloc>::iterator) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; typename _Alloc::rebind<_CharT>::other::pointer = char*]'
 4714 |       erase(iterator __position)
      |       ^~~~~
/opt/rh/devtoolset-9/root/usr/include/c++/9/bits/basic_string.h:4714:7: note:   candidate expects 1 argument, 2 provided
/opt/rh/devtoolset-9/root/usr/include/c++/9/bits/basic_string.h:4734:7: note: candidate: 'std::basic_string<_CharT, _Traits, _Alloc>::iterator std::basic_string<_CharT, _Traits, _Alloc>::erase(std::basic_string<_CharT, _Traits, _Alloc>::iterator, std::basic_string<_CharT, _Traits, _Alloc>::iterator) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; typename _Alloc::rebind<_CharT>::other::pointer = char*]'
 4734 |       erase(iterator __first, iterator __last);
      |       ^~~~~
/opt/rh/devtoolset-9/root/usr/include/c++/9/bits/basic_string.h:4734:40: note:   no known conversion for argument 2 from '__normal_iterator<const char*,[...]>' to '__normal_iterator<char*,[...]>'
 4734 |       erase(iterator __first, iterator __last);
      |                               ~~~~~~~~~^~~~~~
      |                               ~~~~~~~~~^~~~~~

The error looks reasonable to me because as per C++ documentation, both arguments to std::basic_string::erase should either be of type iterator or const_iterator.

So when it works (e.g. here), what allows it to work ?

mardi 20 septembre 2022

Why does this simple code keep showing this error?

So this is a simple function to calculate the sum of digits of a number. But I keep getting two errors when I try and run it. Here is the code:

#include <iostream>
#include<climits>
int main(){
    int x;
    std::cout<<"Enter a number : ";
    std::cin>>x ;
    int myfunction(x){
        int count;
        while (x<0){
            x%10;
            count+=1;
         }
        return count;
    }
    int z=myfunction(x);
    std::cout<<z;
return 0;  
}

I'm not really worried about whether the function accurately counts the number of digits. I just want to know why it keeps showing these two error messages:

error: 'myfunction' cannot be used as a function

Replacement for `std::bind` with Visual Studio 2019?

I've got code that compiles with Visual Studio 2017 that uses std::bind:

std::unique_lock<std::mutex>    m_lock(m_mutex_wait_for_message);
m_cond_variable.wait(m_lock, std::bind(&Logging::is_message_available, this));
std::lock_guard<std::mutex>     lock_guard(m_mutex_pushing_message);

We are now compiling using VS2019 and it's complaining with errors:
'bind': is not a member of 'std'
'bind': function does not take 2 arguments

CppReference.com says "Until C++20"

Questions:

  1. What is the replacement for std::bind in the mutex locking code above?
  2. What is the replacement for std::bind?

fscanf parse data (format specifier) C++

I have a struct like so:

struct Office {
char city[50];
int employees;
char desc[200];
}

struct Office office[100];

Then I want to fill the office array within a loop until reach end of file.

here is my data:

Toronto
    151: This is HQ

Vancouver
    23: This is branch office

London
    12: This is euro branch

Take this as an example:

Toronto
    151: This is HQ

So here I want to parse it to struct:

city = "Toronto"
employees = 151
desc = "This is HQ"

Notice: After city name in the new line before the number of employess, there is TAB (4 spaces)

I have had an implementation like so, but seems it does not work properly:

int function LoadOffices(const char *f) {
  int res = 1;
  char buf[500];
  char city[50];
  int emp;
  char desc[200];
  struct Office offices[100];
  FILE *fp = fopen(f, "r");

  if (fp) {
    while (fgets(buf, sizeof(line), fp) != nullptr) {
      if (i == 0) {
        rewind(fp);
      }
      i++;
      if (fscanf(fp, "%[^\n]", city) == 1) {
        strncpy(offices[i].city, city, 50);
      } else if (fscanf(fp, "%d[^:]:%[^\n]", &emp, desc) == 2) {
        offices[i].employees = emp;
        strncpy(offices[i].desc, desc, 200);
      }
    }
    res = 0;
  } else {
    res = 1;
  }

  fclose(fp);
  return res;
}

I just want to know how to deal with TAB and empty lines

lundi 19 septembre 2022

`getLine` function skipping the final, blank line in an input file

I want to find out the character length of each of the lines in a separate file, which is test.txt. test.txt contains two lines: the first contains hello, and the second is blank.

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main() {
    ifstream inFile;
    inFile.open("test.txt");
    string currline;

    while (getline(inFile, currline)) {
      cout << currline.length() << endl;
    }
}

When executing this program and inputting 'test.txt', I was expecting the output to be 5 0. However, the output was simply 5, which meant that the second line of test.txt was being ignored. How do I solve this issue without modifying the input file, or using a new modified file?

How to manage a triple pointer in C++

I tried to solve a problem with triple pointer using dynamic memory but I had a problem. I tried to create a triple pointer with 2 static dimensions to try to count the exact number of character strings that I would need. The reason of using that static pointer is to assign the correct number of subjects to the students that I will show soon. In this problem I had 2 txt docs. First I had a number of students and their IDs

Then I had a number of registers with many subjects that I need to add to the students according their IDs or codes I tried to create a static double pointer to save and add the subjects to the students but I didnt know how to manage the double static pointer

Another functions in C++

C++: How do I route file input stream to cout in one statement? inputStream >> cout doesn't work

How do I take output from a stream and link directly into cout.

For example: inStream >> cout... This doesn't actually work through. PLZ HELP

Having trouble understanding two questions

The first one is:

● Write a C++ program to estimate PI using the numerical integration method. Your program should ask the user to input the total number of rectangles n that are used to estimate the area of a quarter of the circle with radius r = 1. ● Define PI = 3.14159265 and report your error when you use n = 10, 10^2, 10^3 and 10^4 rectangles. Please include your error calculation inside your code, and output the estimated PI(10 digits after the decimal point) and error(5 digits after the decimal point) at the same time. ● error = [(estimated_PI – true_PI) / true_PI] * 100% EX: if the input is: 10 the output is: 3 The estimated value of pi is 3.3045184612 with n=10. The error is 5.18609%

and the second one is:

● Write a C++ program to estimate PI using the Monte Carlo method. ● Your program should ask the user to input the total number of random points (xi, yi) we will generate in the simulation. Use “srand(time(0))” function ● Define PI = 3.14159265. Estimate PI value(10 digits of precision) and the error(5 digits of precision) when you use 10^3 ,10^4, 10^5 and 10^6 samples. ● error = [(estimated_PI – true_PI) / true_PI] * 100% ● After you find the value of Pi, use that to find the area of an ellipse5 digits of precision) with semi-major axis as 10 and semi minor-axis of 7, and report the “estimated PI value”, “error”, “estimated ellipse area” simultaneously. ● Hint: Ellipse area = πab ● Your answer might not be exactly the same as the output below due to randomness. EX: if the input is: 1000 the output is: The estimated value of pi is 3.1119999886 with n=1000. The error is -0.94197% The estimated ellipse area is 217.84000

Could someone please walk me through these problems or in some way help me to understand them?

dimanche 18 septembre 2022

Need some help on this problem to merge these two codes

 #include <iostream>
using namespace std;
int main()
{
    char c;
    int n;
    cout << " Please enter a letter of the Alphabet and a decimal number";
    cin >> c >> n;
    if (c == 'a'|| c== 'e'|| c== 'i'|| c== 'o'|| c== 'u'||c == 'A'|| c== 'E'|| c== 'I'|| c== 'O'|| c== 'U' )
    {
        cout << c <<  " is a vowel" << endl;
    }
    else
    {
        cout << c << " is a consonant" << endl;
    }

    float x;
    cin >> x;
        if (x<0)
            cout << x << " is less than 0";
        else if (x>0&&x<100)
            cout << x << " is in range ";
        else
            cout << x << " is out of bounds";

        return 0;
}

The output is this when A, 41.5 is entered:

A is a vowel nan is out of bounds.

I would like for the code to be able to find the answer to both and tell me whether or not it is below 0, in range, or out of bounds and also say that the letter is a vowel or a consonant, how could I go about doing this?

samedi 17 septembre 2022

Issue in operator overloading using smart pointers

I am learning smart pointers in C++11. I am facing an compilation error with operator overloading using smart pointers. Can someone please suggest where I am doing wrong.

Below is the code

#include <iostream>
#include <memory>

using namespace std;

class myClass
{
   private:
   string name;

   public:
   myClass() { }
   myClass(string n) : name(n)  { }

   shared_ptr<myClass> operator + (shared_ptr<myClass> &obj1, shared_ptr<myClass> &obj2)
   {
      cout << "Operator Overloading" << endl; 
      return make_shared<myClass>(obj1 + obj2);
   }

   void print()
   {
      cout << name << endl;
   }
};

int main()
{
   shared_ptr<myClass> myPtr1 = make_shared<myClass>("Hello");
   myPtr1->print();

   shared_ptr<myClass> myPtr2 = make_shared<myClass>("Operator Overloading");
   myPtr2->print();

   shared_ptr<myClass> myPtr3;
   myPtr3 = myPtr1 + myPtr2; //Calling Operator overloading
   myPtr3->print();

   return 0;
}

Using directive refers to implicitly-defined namespace 'std'

enter image description here

So I put using namespace...... after #include. However, im still getting this error message?????

C++ programming for beginners [closed]

What are the best and most necessary extensions for c++ in visual code? i just started c++ and I'm not sure what are the extensions I need for it to run smoothly in visual code

vendredi 16 septembre 2022

i am trying to display employees based on their designation like hr,developer like that i tried a code but it is not displaying output

iam trying to display employees based on their designation like hr,developer like that i tried a code but it is not displaying output

void searchDeptReport()
{
    system("cls");
    char department[20];
    int i;
    ;
    bool found = false;
    cout << "\nYou can Search only through the designation of Employees\n\n";
    cout << "\nEnter the Department to get report : ";
    cin >> department;
    for (int i = 0; i <= num - 1; i++)
    {
        if (emp[i].designation == department)
        {
            cout << "\nName\t  Emp ID\tGender\t Designation " << endl;
            cout << "------------------------------------------------\n";
            gotoXY(0, 7);
            cout << "Name : " << emp[i].name << endl;
            gotoXY(11, 7);
            cout << "Employee Id : " << emp[i].code << endl;
            gotoXY(21, 7);
            cout << "Gender : " << emp[i].gender << endl;
            gotoXY(35, 7);
            cout << "Designation : " << emp[i].designation << endl;
            found = true;
            cout << "\n\nPress Any key for Menu..";
        }
    }

    if (!found)
    {
        cout << "\n\nNo records Found...!!!\a";
        cout << "\n\nPress Any key for Menu..";
    }
    getch();
}

enter image description here

memory steps while defining variable - are they true?

Lets say we are defining a variable :

float myFloat{3};

I assume that these steps are done in memory while defining a variable, but I am not certainly sure.

Initial Assume: Memory is consist of addresses and correspond values. And values are kept as binary codes.

1- create binary code(value) for literal 3 in an address1.

2- turn this integer binary code of 3 to float binary code of 3 in the address2. (type conversion)

3- copy this binary code(value) from address2 to the memory part created for myFloat.

Are these steps accurate ? I would like to hear from you. Thanks..

jeudi 15 septembre 2022

How to initialize the array-like member variable in the constructor?

How to initialize the array-like member variable?

The visual studio code says:

no matching function for call to 'Node::Node()' gcc line 12 col 9

const int N = 100;

struct Node {
    int val, ch[2];
    /**
    void init(int _val) {
        this->val = _val, this->ch[0] = this->ch[1] = 0;
    }*/
    Node (int _val): val(_val) {
        this->ch[0] = this->ch[1] = 0;
    }
} tree[N];    // <--------- this is line 12


int main() {
    int a;
    cin >> a;
    tree[0] = Node(a);
}

How to implement warning / error message reporters library

I`ve started to work on some project. Their error reporter mechanism doens`t look good

  1. Every time they find an error they prepare string (locally)
  2. Report it via some function It is very inconvenient - the project is big and looks that the better way to have some module which has all error message concentrated in some file/data structure. When error occurs just report an error by its id and appropriate string will be emitted. The possible issue is that thre are some errors which are parametrized by some runtime info Is there some project / design that you can advice for such error reporter. How to handle parametrized error (number of parameters (and types) vary for different errors - could be one int or 10 strings , etc) Thanks

mercredi 14 septembre 2022

keeping dynamically allocated memory and vectors post scope in c++11

I am learning c++ and came across an issue that I'm not able to resolve. I have read dozens of articles but still not able to figure out the solution. Here are the details: I have created a simple class with two members

uint8_t* atlas;
std::vector<int> vect;

In the constructor of class, I'm allocating memory and initializing the vector like this:

uint8_t* atlas = new uint8_t[512 * 512]();
std::vector<int> vect{ 10, 20, 30 };

Later in another function when accessing these two variables:

std::cout << vect.size() << std::endl;
if(atlas == nullptr) { 
    std::cout << "null atlas" << std::endl;
    return;
} 

The size of the vector is 0 and the atlas is nullptr. After reading several articles about this issue I came across several things such as heap, stack, scope, and smart pointers. The problem is that locally assigned variables are lost as soon as the function or scope ends. My question is that atlas and vect are the members of the class, not locally assigned variables then why the data is getting lost? As per the documentation, the dynamically allocated memory remains intact, it's the pointer that is lost tracking of it.

Several articles suggested that this problem can be solved using smart pointers but I'm not able to figure out, how it can be done. What I need is to keep the dynamically allocated data and vector safe so that I can access them in another function.

How to store pointers to callback functions with different signatures in an STL container (map

I'm currently in a situation where I want to store function pointers in an std::map<string, func> . Specifically, these functions are callback functions which have different signatures, and importantly they have different return types which is the heart of my problem.

For example:

// callback 1
GstPadProbeReturn callback_1(GstPad *pad, GstPadProbeInfo *info, gpointer u_data);

// callback 2
GstFlowReturn callback_2(GstPad *pad, GstPadProbeInfo *info, gpointer sharedPtr)

// callback 3
void callback_3(GstElement *element, GstPad *pad, gpointer u_data);

/* somewhere else in the code */
std::map<std::string, functionPtr> cb_map;

map["func1", callback_1];
map["func2", callback_2];
map["func3", callback_3];

and so I can pull the callback I want out of the map and connect the callbacks in the code, which with gstreamer can be done in the following way:

gst_pad_add_probe(probe_pad, GST_PAD_PROBE_TYPE_BUFFER, callback_1, NULL, NULL);

The problem here is callback_1 must match a return type as specified by gst_pad_add_probe while other functions can accept void.

I tried several approached but I keep getting stuck at either not being able to store functions of different signatures in std::map or not being able to pass std::function<void> in the calling function.

I tried the following:

template <class F, class... Args>
inline auto FuncWrapper(F &&f) -> decltype(f)
{
  return f;
}

std::map<std::string, std::function<void>()> cb_map;

auto cb1 = FuncWrapper(&callbacks_1);

this->cb_padprobereturn_map.emplace("one", cb1); // doesn't work 
}

Apologies if this is not clear, I wasn't sure how to succinctly explain this problem. I'm also not well versed enough in c++ to use things such as std::variant

Any help is appreciated!

How to create AOM codec in gcc 12.2 and newer under Windows 64bit?

I want to produce codec without SIMD and assembler. I'm using basic functions -std=gnu++11 -ftree-vectorize -g0 -O3 -DWINVER=0x0602 -D_WIN32_WINNT=0x0602 -DWIN32_LEAN_AND_MEAN=/"/" -DNOMINMAX.

The problem is that when I create AOM codecs in GCC 11.3.X they work. On newer compilers GCC 12.2 and gcc13.0 no longer work. What were new features added to these compilers?

Strange thing. Other libraries have no problem: libjpeg-turbo, libpng, libtiff, dav1d, libgav1, avif, svt-av1, openhtj2k, openjph, openjpeg2000, ...

mardi 13 septembre 2022

How can std::reference_wrapper

[Solved] Thank you all, I didn't even know about user-defined conversion function and how it works.

Why it's possible to use std::reference_wrapper::operator+=, if such operator does not exist, are there some implicit conversions?

#include <iostream>
#include <functional>
#include <boost/type_index.hpp>

using boost::typeindex::type_id_with_cvr;

template <typename C>
void test(C c)
{
    c += 1;
}

int main()
{
    int a = 3;
    test(a);
    std::cout << a << std::endl;
    test(std::ref(a));
    std::cout << a << std::endl;dd
}

Output: 3 4

To check that template works perfectly fine:

void test_2(std::reference_wrapper<int> c)
{
    c += 1;
}
int main()
{

    int a = 3;
    test_2(std::ref(a));
    std::cout << a << std::endl;
}

Output: 4

Still works as before. How is that possible?

Funny thing, that in auto d = b + c. d has an integer type.

int main()
{
    auto b = std::ref(a);
    auto c = std::ref(a);
    auto d = b + c;
    std::cout << type_id_with_cvr<decltype(d)>).pretty_name() << std::endl;
}

Output: int

What is using T::T

I read this article and don't understand meaning of the part of code:

template <typename T> struct counted : T, private instance_counter<T>
{
  using T::T;
};

It must be something simple as "make visible all names from namespace" but I don't completely catch.

Should I use dynamic allocations?

I have following c++ code (psuedo)

while(!fileEnd)
{
    rectD *rD = new rectD();
    symbol *sb = new symbol(rD);
    
    while( true )
    {
        if(closing brace)
        {
            sb->rD->isSymbol = true;
            sb->shapes[currentSymName] = *(sb->rD); // shapes is a std::map
            allSymbol[currentSymName] = sb; // allSymbol is a std::map
            break;
        }
        else
        {
            if(condition 1)
               sb->fun1();
            if(condition 2)
               sb->fun2();
        }
    }
}     
   

Now in rest of the program I use shapes and allSymbol map.

Here I want to ask,

Is new keyword necessary here ?

I know when we create object using new then it is created on heap memory and without using new, object is created on satck memory.

Heap memory lives until we delete it and stack memory gets deleted once function scope gets end.
In above code, Once the scope of above function ends I am no longer using *rD and *sb. But in through out program I am using std::map , shapes and allSymbols which contains *sb and *rD.

So I am confused, whether should I use new keyword or not ?
And if I have to use it, where should I release the memory ( using delete keyword) to avoid memory leak ?

unique_lock same mutex in different thread

i am looking at this piece of code:

#include <chrono>
#include <iostream>
#include <map>
#include <mutex>
#include <shared_mutex>
#include <string>
#include <thread>

bool flag;
std::mutex m;

void wait_for_flag() {
  // std::cout << &m << std::endl;
  // return;
  std::unique_lock<std::mutex> lk(m);
  while (!flag) {
    lk.unlock();
    std::cout << "unlocked....." << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::cout << "sleeping....." << std::endl;
    lk.lock();
    std::cout << "locked by " << std::this_thread::get_id() << "....."
              << std::endl;
  }
}

int main(int argc, char const *argv[]) {
  std::thread t(wait_for_flag);
  std::thread t2(wait_for_flag);
  std::thread t3(wait_for_flag);
  std::thread t4(wait_for_flag);
  std::thread t5(wait_for_flag);

  t.join();
  t2.join();
  t3.join();
  t4.join();
  t5.join();

  return 0;
}

I am new to this, and I thought mutex can only be acquired by one thread. I got two questions:

  1. why there is no deadlock among those threads, e.g. if thread A runs lk.unlock(), then thread B runs lk.lock() and then thread A runs lk.lock().
  2. what does it mean we define a new unique_lock in every thread associating to the same mutex lock (which is called m in here)

Thanks

lundi 12 septembre 2022

Is there a way to remove the last template parameter of variadic template methods?

I'm working on creating a simple reflector in C++11, it stores function pointers of instances functions as:

static std::unordered_map<std::string, std::pair<void(EmptyClass::*)(void), int>>* methods;
template<typename ClassType, typename returnType, typename... Args>
static void RegistFunction(std::string name, returnType(ClassType::* func)(Args... args)) {
    (*methods)[name] = std::make_pair((void(EmptyClass::*)())func, sizeof...(Args));
}

template<typename ReturnType, typename ClassType, typename... Args>
static ReturnType ExecuteFunction(ClassType* object, std::string name, Args... args) {
    if (object == NULL) return;
    ReturnType(ClassType:: * func)(Args...) = (ReturnType(ClassType::*)(Args...))(*methods)[name].first;
    return (object->*func)(std::forward<Args>(args)...);
}

But when I want to call ExecuteFunction, the number of arguments may be more than the number that function pointer actually accepts. So I need to remove some arguments from the tail of argument list, but it seems I can only remove from head.

template<typename ReturnType, typename ClassType, typename Arg, typename... Args>
    static ReturnType ExecuteFunction(ClassType* object, std::string name, Arg arg, Args... args) {
        if (sizeof...(Args) + 1 > (*methods)[name].second) {
            return ExecuteFunction<ReturnType>(std::forward<ClassType*>(object), std::forward<std::string>(name), std::forward<Args>(args)...);
        }
        if (object == NULL) return;
        ReturnType(ClassType:: * func)( Arg, Args...) = (ReturnType(ClassType::*)(Arg, Args...))(*methods)[name].first;
        return (object->*func)(std::forward<Arg>(arg), std::forward<Args>(args)...);
    }

Is there any solution to remove arguments at the tail of variadic method template?

dimanche 11 septembre 2022

C++11: passing a temp object to a ctor, doesn't call move constructor, why? [duplicate]

I was trying to see why move constructor is called, as below:

#include<iostream>
#include<utility>
using namespace std;
struct M{
  M(){cout<<"ctor\n";}
  M(const M&m){cout<<"copy ctor\n";}
  M(M&&m){cout<<"move ctor\n";}
  M& operator=(const M&m){cout<<"copy operator=\n"; return *this;}
  M& operator=(M&&m){cout<<"move operator=\n"; return *this;}
};
int main(){
  M obj1(M{}); // why this prints "ctor", but not "move ctor"?
  cout << "----\n";
  M obj2(move(M{})); // ctor and move ctor, as expected.
  return 0;
}

compile with clang++-14 and msvc-2022, both gave same result:

ctor
----
ctor
move ctor

My question lies in M obj1(M{}): as long as M{} is a temporary object, it's right value, so I expected that move ctor will be called. But in fact not.

Only when I explicitly called M obj2(move(M{}));, this time, ctor + move ctor being called.

So M{} is an r-value, move(M{}) returns an r-value, why they gave different result on object construction?

Thanks!