lundi 31 octobre 2022

VS 2022 C++ DLL dllexport with Classes

Ok, so, DLLs are getting mad annoying. Either because I'm a fool or they are really that complex.

I'm trying to have a DLL which contains a class and then export that class and use it via Run-Time Dynamic Linking, i.e. using LoadLibrary and GetProcAddress functions, without needed to link to a .lib.

I read that it's better to instead of exporting the class itself, you should export a function which returns an instance of said class. Something like this;

extern "C" {
    Threader __declspec(dllexport)* CreateClass()
    {
        return new Threader();
    }
};

How do I then do the whole "GetProcAddress" in the main to access this function. I can't seem to get it to work. I can export a regular function that just returns an int this way no issue, but with the class return I'm struggling. When I try to call the function, the compilier throws error;

LNK2019 unresolved external symbol "public: __cdecl Threader::Threader(void)" (??0Threader@@QEAA@XZ) referenced in function CreateClass

Here's my source code;

Main.cpp

#include <iostream>
#include "Threader.h"
#include "GetClass.h"
#include <Windows.h>

typedef int(__cdecl* MYPROC)(LPCWSTR);
typedef Threader* (* GETMYCLASS)(LPCWSTR);


int wmain()
{

    HINSTANCE hinstLib;
    MYPROC ProcAdd;
    GETMYCLASS ClassAdd;
    BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;

    hinstLib = LoadLibrary(TEXT("ThreaderDLL.dll"));
    if (hinstLib != NULL)
    {
        std::cout << "DLL Loaded" << std::endl;
        ProcAdd = (MYPROC) GetProcAddress(hinstLib, "ThreadFunc");
        GETMYCLASS ClassAdd = (GETMYCLASS) GetProcAddress(hinstLib, "CreateClass");
        if (NULL != ProcAdd && NULL != ClassAdd)
        {
            std::cout << "Func Loaded, Class Loaded"<<std::endl; //**This line runs so ClassAdd is NOT empty**
            fRunTimeLinkSuccess = TRUE;
            ThreadFunc();
            Threader* threader = CreateClass(); //This wont work causes build to fail
        }
        // Free the DLL module.

        fFreeResult = FreeLibrary(hinstLib);
    }

    int i = 0;
    double j = 0;
    std::cout << "Hello World!\n";

    Sleep(2000);

    std::cout << "WakaWaka" << std::endl;
    Sleep(2000);

    return i;

}

Threader.h

#pragma once
#include <thread>
#include <iostream>
#include <vector>
#include <atomic>
#include <mutex>


class Threader
{
public:

    Threader();
    ~Threader();
    void makeThread();
    int ThreadFunc();
    std::vector<std::thread> threads;
    std::atomic<bool> running = true;
    static std::mutex mtx_;
    std::atomic<int> i = 0;

private:



};


extern "C" {
    Threader __declspec(dllexport)* CreateClass()
    {
        return new Threader();
    }
};


extern "C" {
    int __declspec(dllexport) __cdecl ThreadFunc()
    {
        int i = 0;
        while (i < 500)
        {
            std::cout << i << "\n";
            i++;
        }
        return 0;
    }
};

Threader.cpp

#include "Threader.h"
#include <Windows.h>

std::mutex Threader::mtx_;

Threader::Threader()
{
}

Threader::~Threader()
{
    //running = false;
    std::cout << "Killing Class and joining threads" << std::endl;
    for (auto& t : threads)
    {
        t.join();
    }

}

void Threader::makeThread()
{
    std::cout << "Making Class thread" << std::endl;
    //std::thread thread(&Threader::ThreadFunc, this);
    threads.push_back(std::thread(&Threader::ThreadFunc, this));
    //thread.join();
    //return 0;
}

int Threader::ThreadFunc()
{

    std::cout << "Class Thread Started" << std::endl;
    while (running)
    {

        while (i < 100)
        {
            std::lock_guard<std::mutex> lck(mtx_);
            //std::cout << "i = " << i << "\n";
            i++;
            Sleep(1000);
        }
        running = false;
    }
    std::cout << "Class Thread Ending" << std::endl;
    return 0;
}

Do I have to put the declaration of CreateCLass in the .h and the implementation in the .cpp? I know it has something to do with the compilier not finding the implementaiton or something like that. But I'm pretty sure I tried that and it still didn't work.

Plz help.

How to get a generic callback function or method with any types of return or parameters?

I'm making some API and want to allow app developers to put their own callback function with any return types and any number of parameters. Below code is example I expect to work. I wonder how to define ?<?> userfunc in MyAPI.h

// MyAPI.h

using namespace API {
/**
* Executes callback function after a random time in its own thread.
* @param userfunc User defined callback function.
**/
void SetCallback(?<?> userfunc);
}
// application.cpp

#include "MyAPI.h"
#include <chrono>
#include <format>
#include <iostream>

std::string get_current_datetime() {
  const auto now = std::chrono::system_clock::now();
  return std::format("{:%d-%m-%Y %H:%M:%OS}", now);
}

bool callback_1(bool* triggered, std::string* registration_time) {
  *triggered = true;
  std::cout << "CALLBACK_1" << std::endl;
  std::cout << "registered: " << registration_time << std::endl;
  std::Cout << "triggered : " << get_current_datetime() << std::endl;
  return true;
}

int callback_2(int* triggered) {
  *triggered = 1;
  std::cout << "CALLBACK_2" << std::endl;
  return 1;
}

int main(void) {
  bool is_triggered_bool = false;
  int is_triggered_int = 0;
  std::string curr = get_current_datetime();
  API::SetCallback(std::bind(&callback_1, &is_triggered_bool, &curr));
  API::SetCallback(std::bind(&callback_2, &is_triggered_int))
  Sleep(3000);
  if (is_triggered_bool && is_triggered_int == 1) return 0;
  else return -1;
}

Any advice will appreciate

Why I am getting "expected primary-expression before ‘int’ in callback function?

I have just started to learn C++. I want to call a function inside another function kinda of call back. I wrote this code. But I am getting the

error error: expected primary-expression before ‘int’
     return hello(1,2, ta(int y));
                          ^~~

Code:

#include <stdio.h>
#include <iostream>

int thirds(int x){
    return x + 1;
}

template <typename T, typename B, typename L>
int hello(T x, B y ,L z ){
    
    int first = x + 1;
    int second = y + 1;
    int third = z(5);
    
    return first + second + third;
}

int add(){
    return hello(1,1, thirds(int y));
}

int main()
{
    std::cout<<add();

    return 0;
}

Live

My expected output is 10.

Can someone tell me what need to be change? Note: I strictly need all the functions

dimanche 30 octobre 2022

Are elements of a 'const std::vector<:string>' immutable as well? (in C++11)

This will compile:

std::vector<std::string> test{"hello"}
std::cout << tt.[0] << '\n';
tt[0].append(" world");
std::cout << tt.[0] << '\n';

Output:

hello
hello world

This will not:

const std::vector<std::string> test{"hello"}
std::cout << tt.[0] << '\n';
tt[0].append(" world");
std::cout << tt.[0] << '\n';

More importantly, as expected, this will not compile:

std::vector<const std::string> test{"hello"}
std::cout << tt.[0] << '\n';
tt[0].append(" world");
std::cout << tt.[0] << '\n';

but sadly, neither will this:

std::vector<std::string> test{"hello"}
std::cout << tt.[0] << '\n';

There are many differing answers to questions about immutability of std::vector and details on cppreference.com (Assignable, CopyAssignable...). But getting down to what I'd like to be able to do (so the question is: "how do I do this..."? --

  1. define a std::vectorstd::string that will allow me to ensure the elements, once added, cannot be changed -- but the vector can be changed, including adding new and deleting existing elements and changing their order (std::vector failed though seemed a reasonable approach without understanding the details of std::vector)
  2. define a std::vectorstd::string that will not allow me to change the vector or its elements (const std::vectorstd::string seems to work)
  3. define a std::vectorstd::string that allows the existing elements to be modified but the vector itself will always have the same number and order of elements (this is not particularly interesting to me)
  4. std::vectorstd::string is fully modifiable.

samedi 29 octobre 2022

Formula returns -0 instead of INF in C++

I am new to C++ and am trying to figure out one thing: I am given this formula to count z with different values for m given. All good with most of the values except when m=0. I was expecting to receive INF for z, due to the division by 0 in this part 2 / sqrt(m) but received z= -0 instead. Is there any formal explanation to this? Because if we take z2 = 2 / sqrt(m) separately, it will result in inf. I need to write a report and have no idea on how to explain this, found nothing in C++ documentation. Using Microsoft Visual Studio Code 2017 if it matters. Would appreciate your help!

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#define _USE_MATH_DEFINES 
#include <math.h>
#include <ctgmath>

int main() {

    float m;
    cout << " Enter the 'm' value: ";
    cin >> m;
    float z;
    float z2;

    z = sqrt(pow((3 * m + 2), 2) - 24 * m) / (3 * sqrt(m) - 2 / sqrt(m));
    z2 = 2 / sqrt(m);
    cout << " \n When 'm' is " << m << ", 'z' value is: " << z << "; 'z2' value is: " << z2 << endl;


    return 0;
}

The console

tried to use double type instead of float, didn't help :(

Why constructors of a class with a virtual base class cannot be constexpr?

The restriction hasn't been changed since C++11, and the corresponding restriction for destructors were added in C++20. The newly adopted P2448R2 talked about this, but didn't touch the reason.

Perhaps it was N1980 (the proposal for constexpr before ) that added this restriction at first, but I failed to find the reason or motivation in it.

I also wonder whether there's anyone wanting to relax this restriction.

exe file from c++ code does not work when compiled from cmd [duplicate]

I'm writing a c++ project in Clion I have 3 files: main.cpp FileOperations.h FileOperations.cpp

#include <iostream>
#include <string>
#include <sstream>
#include "FileOperations.h"

using namespace std;

int main() {


    cout << "hello" << endl;

    /*string inputFileName;

    cin >> inputFileName;

    vector<string> inputs = FileOperations::readFromFile(inputFileName);


    for (const string& line:inputs) {

        cout << line << endl;

    }*/


}

This is my main func. Right now it is only supposed to print hello to the screen. When I compile from command line with different ways, it behaves differently. And it works on Clion automated run

g++ main.cpp FileOperations.cpp -o myProgram
./myProgram 

It does not give any output when I do so as above in Clion, also when I do it a with windows terminal, exe file is broken

There must be a problem with linking but why ?

And FileOperations.o file is created so there are no compiler errors? Why do I have a problem with exe file even though I have no errors?

(g++ main.cpp -o myProgram works)

vendredi 28 octobre 2022

Is there a better algorithm for this code? for storing of particular text from .txt file to std::vector<:string>?

I have this name_and_id.txt file which contains Name of Users and its IDs.

The file contains:

0. Heal: A24-1234
1. Hael: A25-4567
2. Hela: A26-8910
3. Hale: A27-1112

What I wanted to do is to get rid of the Name of Users and to just left with IDs only. In my first output it works fine -

First output: (works fine)

A241234
A254567
A268910
A271112

But if I add more Name of Users and IDs (add new line first before the new name of users and ids)

Adding new Name of Users and IDs:

0. Heal: A24-1234
1. Hael: A25-4567
2. Hela: A26-8910
3. Hale: A27-1112

4. Test1: A28-1314
5. Test2: A29-1516
5. Test3: A30-1718

In my second try, it gives me an output like this one:

A241234
A254567
A268910
A271112
Test1
Test2
Test3

Here's my code:

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <utility>
#include <vector>

auto main() -> int {
  
    std::fstream user_file{};
    
    const char space_char{' '}; //NOTE - space delimiter 
    std::string entries_by_line{};
    std::vector<std::string> data_entries{};
    std::stringstream entries_in_file{};
    std::string entries_data_imported_file{};
    std::vector<std::string> tokenized_data_imported_file{};
  
    user_file.open("name_and_id.txt");
    if(user_file.is_open()) {
        while(std::getline(user_file, entries_by_line)) { 
            data_entries.emplace_back(entries_by_line); //REVIEW - store data (without new lines) from `.txt` file into vector named `data_entries`
        }
  
        std::copy(
            data_entries.begin(),
            data_entries.end(),
            std::ostream_iterator<std::string>(entries_in_file, " ") //REVIEW - copy contents (with spaces) of vector `data_entries` to a std::stringstream named `entries_in_file`
        );
    
  
        std::stringstream entries{std::move(entries_in_file.str())}; //REVIEW - store content of entries_in_file.str() to std::stringstream named `entries`
    
        while(std::getline(entries, entries_data_imported_file, space_char)) {
            entries_data_imported_file.erase(
                std::remove_if(
                    entries_data_imported_file.begin(),
                    entries_data_imported_file.end(),
                    ispunct //REVIEW - remove punctuations
                ),
                entries_data_imported_file.end()
            );
            tokenized_data_imported_file.emplace_back(entries_data_imported_file); //REVIEW - store data (without punctuations) to vector `tokenized_data_imported_file`
        }
    
        if((tokenized_data_imported_file.size() % 2) > 0) { 
            tokenized_data_imported_file.pop_back(); //REVIEW - remove every odd values in vector `tokenized_data_imported_file` to only left the rhs text
        }
      
        for(size_t i{}; i != (tokenized_data_imported_file.size() / 2); ++i) {
            tokenized_data_imported_file.erase(tokenized_data_imported_file.begin() + i); 
            std::cout << tokenized_data_imported_file[i] << std::endl;
        }
    }
    user_file.close();
  
}

Can you also guys suggest a better algorithm for this type of problem?

Why can't i get the output i need from the report?

I'm new to programming and c++ so please bare with me. My program is not running for some weird reason i've tried to comment out the sections with other errors and nothing has changed, I tried different libraries and that didn't helped either. I tried so many more things that I can't even list them.

#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

//read the number of bots
int botsCount = 5;
combatFile >> botsCount;
//creat an array to hold the botsPower
int botsPower(botsCount);
float bossPower;

int microMissiles = 10;
float defenseMatrix = 100.0; 

//calculate and load defense matrix
float matrix_power = (botsPower, botsCount, bossPower);
float matrixPowerRequired = matrix_power = (botsPower, botsCount, bossPower);
return matrixPowerRequired;

//void load_dva (defenseMatrix, matrixPowerRequired);

//calculate micro missiles
template <typename T>
T single_missile_power(T bossPower) {return 5 * bossPower;}
for (int i = 0; i < botsCount; i++)
T single_missile_power(T botsPower) {return 2 * botsPower[9]};
{
if (T single_missile_power(T botsPower[13]) <= 10) {
    T single_missile_power(T botsPower[13]) * 2;
}
else {
    T single_missile_power(T botsPower[13]) * 5;
}
return single_missile_power;
}

void load_dva(float * defenseMatrix, float matrixPowerRequired)
{
    if (*defenseMatrix > matrixPowerRequired)
    *defenseMatrix = matrixPowerRequired;
}
void load_dva(int * microMissiles, float missilePowerRequired)
{
    if (*microMissiles < missilePowerRequired)
    *microMissiles = ceil(missilePowerRequired / 80);
}

int main() {
    fstream combatFile;
    //open file
    combatFile.open("combat_info.txt", ios::in);
    string line;
    //check file open
    if (combatFile.is_open()) {
        cout << "file fail to open" << endl;
        }
        combatFile.close();
    
    float matrixPowerRequired = matrix_power;
    float missilePowerRequired = single_missile_power<float>(bossPower);
    for (int i = 0; i < botsCount; i++)
    missilePowerRequired += single_missile_power<int>(botsPower);
    load_dva(&defenseMatrix, matrixPowerRequired);
    load_dva(&microMissiles, missilePowerRequired);

    fstream myFile;
    //open file
    myFile.open("report.txt", ios::out);
    if (myFile.is_open()) {
        myFile << "D. Va's Combat Report\n";
        myFile << "Combat with " << botsCount << " enemy bots and one enemy boss with power " << bossPower << "\n";
        myFile << "Loaded mech with " <<microMissiles << " micro missiles and the defense matrix with power " << defenseMatrix << "\n";
        myFile << "Ready for combat!";
        myFile.close();
    }
    return 0;
}

I'm suppose to get the output

D.Va's Combat Report
Combat with 5 enemy bots and one enemy boss with power 87.15.
Loaded mech with 10 micro missiles and the defense matrix with power 127.15.
Ready for combat!

from the report or code that i typed which is

fstream myFile;
    //open file
    myFile.open("report.txt", ios::out);
    if (myFile.is_open()) {
        myFile << "D. Va's Combat Report\n";
        myFile << "Combat with " << botsCount << " enemy bots and one enemy boss with power " << bossPower << "\n";
        myFile << "Loaded mech with " <<microMissiles << " micro missiles and the defense matrix with power " << defenseMatrix << "\n";
        myFile << "Ready for combat!";
        myFile.close();
    }
    return 0;
}

but its not running.

I'm even getting an error message for me for saying i is not a data type I don't know what else to do.

for (int i = 0; i < botsCount; i++)
T single_missile_power(T botsPower) {return 2 * botsPower[9]};
{
if (T single_missile_power(T botsPower[13]) <= 10) {
    T single_missile_power(T botsPower[13]) * 2;
}
else {
    T single_missile_power(T botsPower[13]) * 5;
}
return single_missile_power;
}

picture of error ERROR

output OUTPUT

jeudi 27 octobre 2022

Building red-black tree with vector of lists in C++

 vector<list<Nodo<string>*>> lista;

i have this vector of lists and I'm trying to write a method to insert elements into it

  template <typename T> void HashRBT<T>:: riempimento()
{
     for(auto &it:vett_dati) 
    {   int key=it.first;
        string value=(it.second);
        int id=hashFunctionDivsion(key); 
        Nodo<T> *x=rb->searchNodo(rb->getRoot(),id);
        if(x==rb->getNillT()) 
        {
         rb->insertNodoRB(id,value);
        }

      else {  
        lista.resize(getDim());
        Nodo<T> *y= new Nodo<T>(id,value);
       lista.at(id).push_front(y); //inserimento in testa
      }
    }
    Print_Lista(); 
}

now in the else block is where I go to insert the elements in this vector of lists but I don't understand why if I comment the resize statement this doesn't work and I get an error like this: vector :: _ M_range_check. I would like someone to explain to me what happens in memory? what am i allocating with that resize?

Re-write the two lines that instantiate the two Book objects so that they are created on the heap [closed]

How to do this problem?

Dont know how to do it need help.

mercredi 26 octobre 2022

Idiomatic C++11 for delegating template specialisations to a default implementation

I'm making a struct Box<T> that handles some data. The specifics are unimportant.
An important note however is that Box<T> can store a pointer, but it might not. So both Box<int> and Box<int *> are valid. Obviously, if we own Box.data, we're going to need to delete data if it is a pointer type. Here's a solution I came up with that works in C++11:

template <typename T> struct BoxTraits;

template <typename T> struct Box {
    using traits_t = BoxTraits<T>;

    T data;

    ~Box() = default; // not required, I know

    T get_data() { return traits_t::get_data(this); }
};

template <typename T> struct Box<T *> {
    using traits_t = BoxTraits<T *>;

    T *data;

    ~Box() { delete data; }

    T *get_data() { return traits_t::get_data(this); }
};

template <typename T> struct BoxTraits {
    static T get_data(Box<T> *const box) { return box->data; }
};

Box::get_data is here to illustrate an issue with this design pattern. For every single method I want to add to Box, I need to add some boiler plate in each specialisation. Note that I would also need a Box<T *const> specialisation.

This seems like quite a rubbish solution. In C++14, I could use if constexpr with a is_ptr<T> trait and only have to write extra code in the methods that need specialising... Is there any way I can do this is in C++11?

This solution is shorter, cleaner and works for Box<U *const>!

template <typename T> struct is_ptr { static const bool value = false; };

template <typename U> struct is_ptr<U *> { static const bool value = true; };

template <typename U> struct is_ptr<U *const> {
    static const bool value = true;
};

template <typename T> struct Box {
    T data;

    ~Box() {
        if constexpr (is_ptr<T>::value) {
            delete data;
        }
    }

    T get_data() { return data; }
};

mardi 25 octobre 2022

Issue With The Return Type of Functions Definition in Implementation File (C++)

I am trying to define a function with a return type that is an object of a struct. Do I need to do anything special when doing this as a template in an implementation file?

I'm guessing that I have to do something special when the return type isn't a primitive data type, but I can't find what that is. Thank you!

this is my header file

this is my implementation file

how can I send c++ template to a wraped element in parameter pack?

now I have a special requirement.

  1. the quantity of parameters handled by the function is not constant, so I have to use parameter pack in C++

  2. the parameter is std::pair<std:string, template>, but different argument has different type of template, so the args would be like std::pair<std::string, int>, std::pair<std::string, bool>, .... Actually, I need to evaluate the type of each argument and perform different branch by the type. And in C++ only template can transfer typename as argument.

  3. an iterable class would be one of input arguments, so I hope to use the size of this argument instead of the quantity of variable parameters.

so the function would be similar like this:

template<typename... T>
template<typename pair_t> std::pair<std::string, T>
std::vector<ret_class> my_fun(const iterable_class &in_obj, pair_t &...type)
{
    std::vector<ret_class> ret;
    int i=0;
    for(auto arg:type) // ergodic all variable parameters, but I hope to use the iterable_class.size() as the index limit.
    {
        ret.push(handle_fun<arg.second>(iterable_class[i])); // arg.second would change the behavior of handle_fun
        ++i;
    }
    return ret;
}

but it can't pass compile.

Can anybody help me to clarify this issue?

lundi 24 octobre 2022

How to resize dynamically allocated array of std::list?

I created a dynamically allocated array of lists of size 7 which works fine and elements can be pushed to each list in the array. But, when I try to resize the array to size 10 using realloc, which seems to give no error, but when I try to push elements to the lists, I get Segmentation fault error.

Code:

#include <iostream>
#include <list>

int main()
{
    std::list<int> *slots = new std::list<int>[7];

    for (int i = 0; i < 7; ++i)
    {
        slots[i].push_back(i + 1);
        slots[i].push_back(i + 2);
    }

    for (int i = 0; i < 7; ++i)
    {
        for (const auto &slot : slots[i])
        {
            std::cout << slot << ' ';
        }

        std::cout << '\n';
    }

    slots = (std::list<int> *)realloc(slots, sizeof(std::list<int>) * 10);

    // Segmentation fault
    for (int i = 0; i < 10; ++i)
    {
        slots[i].push_back(i);
    }

    return 0;
}

OUtput:

1 2 
2 3
3 4
4 5
5 6
6 7
7 8
Segmentation fault

How to fix this? Thanks.

Cannot assign contents of list attribute in Pybind11 defined class

I have a sparse matrix implementation in C++, and I used pybind11 to expose it to python. Here is the problem:

>>> D1 = phc.SparseMatrix(3, [[0],[1],[2]])
>>> D1.cData
[[0], [1], [2]]
>>> D1.cData[1] = [1,2]
>>> D1.cData
[[0], [1], [2]] #Should be [[0], [1,2], [2]]

In python, I cannot change the contents of the SparseMatrix.cData attribute with the assignment operator. I can change the entire list with D1.cData = [[1],[2],[3]]. This behavior is bewildering to me. D1.cData is just a list, so I would expect that the above code would work.

I suspect it has something to do with my pybind11 code since this behavior is not present in python-defined custom classes. But I have no idea what is wrong (I am a novice programmer). Here is the source code info:

Python Bindings

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

namespace py = pybind11;

#include <SparseMatrix.h>

namespace phc = ph_computation;
using SparseMatrix = phc::SparseMatrix;
using Column = phc::Column;
using CData = phc::CData;

PYBIND11_MODULE(ph_computations, m)
{
    m.doc() = "ph_computations python bindings";

    using namespace pybind11::literals;

    m.def("add_cols", &phc::add_cols);//begin SparseMatrix.h

    py::class_<SparseMatrix>(m, "SparseMatrix")
            .def(py::init<size_t, CData>())
            .def(py::init<std::string>())
            .def_readwrite("n_rows", &SparseMatrix::n_rows)
            .def_readwrite("n_cols", &SparseMatrix::n_cols)
            .def_readwrite("cData", &SparseMatrix::cData)
            .def("__neq__", &SparseMatrix::operator!=)
            .def("__eq__", &SparseMatrix::operator==)
            .def("__add__", &SparseMatrix::operator+)
            .def("__mul__", &SparseMatrix::operator*)
            .def("transpose", &SparseMatrix::transpose)
            .def("__str__", &SparseMatrix::print)
            .def("save", &SparseMatrix::save)
            ;

    m.def("identity", &phc::make_identity);
    m.def("matching_pivots", &phc::matching_pivots);//end SparseMatrix.h
}

SparseMatrix.h

#pragma once

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stdexcept>

namespace ph_computation{

using Int = int;

using Column = std::vector<Int>;//a Column is represented by a vector of indices
using CData = std::vector<Column>;//a matrix is represented by a vector of Columns

//Add columns in Z2
Column add_cols(const Column& c1, const Column& c2);

struct SparseMatrix
{
    size_t n_rows{0};
    size_t n_cols{0};
    CData cData;

    SparseMatrix()=default;

    SparseMatrix(size_t n_rows_, CData cData_):
    n_rows(n_rows_), n_cols(cData_.size()), cData(cData_){}

    SparseMatrix(std::string path);

    bool operator!=(const SparseMatrix &other) const;

    bool operator==(const SparseMatrix &other) const;

    SparseMatrix operator+(const SparseMatrix &other) const;

    SparseMatrix operator*(const SparseMatrix &other) const;

    void transpose();

    void print() const;

    void save(std::string path);
};

SparseMatrix make_identity(size_t n_cols_);

bool matching_pivots(const SparseMatrix& a, const SparseMatrix& b);

}

SparseMatrix.cpp (you probably don't need this)

#include <SparseMatrix.h>

namespace ph_computation {

Column add_cols(const Column& c1, const Column& c2){
    Column c3;
    int idx1{0};
    int idx2{0};
    while(idx1 < c1.size() && idx2 < c2.size()){
        if(c1[idx1] < c2[idx2]){
            c3.push_back(c1[idx1]);
            ++idx1;
        }
        else if(c1[idx1] > c2[idx2]){
            c3.push_back(c2[idx2]);
            ++idx2;
        }
        else {
            ++idx1;
            ++idx2;
        }
    }
    if (idx1 < c1.size()){
        c3.insert(c3.end(), std::next(c1.begin(), idx1), c1.end());
    }
    else if (idx2 < c2.size()){
        c3.insert(c3.end(), std::next(c2.begin(), idx2), c2.end());
    }

    return c3;
}

SparseMatrix make_identity(size_t n_cols_){
    CData cData_(n_cols_);
    for (int j = 0; j < n_cols_; ++j){
        cData_[j] = {j};
    }
    return SparseMatrix(n_cols_, cData_);
}

SparseMatrix::SparseMatrix(std::string path){
    std::fstream f_in;
    f_in.open(path, std::ios::in);
    if(f_in.is_open()){
        std::string n_rows_line;
        std::getline(f_in, n_rows_line); //first line of file contains number of rows
        n_rows = std::stoi(n_rows_line);

        std::string n_cols_line;
        std::getline(f_in, n_cols_line); //second line of file contains number of cols
        n_cols = std::stoi(n_cols_line);

        CData cData_(n_cols);
        cData = cData_;

        std::string line;
        int j = 0;
        int nnz, data;
        while (std::getline(f_in, line)){
            std::stringstream line_str = std::stringstream(line);
            while (line_str >> nnz){
                Column col_j(nnz);
                for (int i =0; i < nnz; ++i){
                    line_str >> data;
                    col_j[i] = data;
                }
                cData[j] = col_j;
            }
            ++j;
        }
        f_in.close();
    }
    else{
        throw std::runtime_error("File did not open.");
    }
}

bool SparseMatrix::operator!=(const SparseMatrix &other) const{
    if (n_rows != other.n_rows || cData != other.cData){
        return true;
    }
    return false;
}

bool SparseMatrix::operator==(const SparseMatrix &other) const{
    return !(*this != other);
    }

SparseMatrix SparseMatrix::operator+(const SparseMatrix &other) const{
        if (n_rows != other.n_rows || n_cols != other.n_cols){
            throw std::invalid_argument("Matrices must have same dimension to add.");
        }

        CData ans_cData;
        for (int j = 0; j < n_cols; ++j){
            ans_cData.push_back(add_cols(cData[j], other.cData[j]));
        }

        return SparseMatrix(n_rows, ans_cData);
    }

SparseMatrix SparseMatrix::operator*(const SparseMatrix &other) const{
        if(n_cols != other.n_rows){
            throw std::invalid_argument("Matrices must have compatible dimensions.");
        }

        size_t ans_rows = n_rows;
        CData ans_cData(other.n_cols);
        SparseMatrix ans(ans_rows, ans_cData);

        for(int j =0; j<ans.n_cols; ++j){
            for(int idx : other.cData[j]){
                ans.cData[j] = add_cols(ans.cData[j], cData[idx]);
            }
        }

        return ans;
    }

void SparseMatrix::transpose(){
        CData cData_T(n_rows);
        for(int j =0; j<n_cols; ++j){
            if(!cData[j].empty()){
                for(int x: cData[j]){
                    cData_T[x].push_back(j);
                }
            }
        }
        cData = cData_T;
        n_rows = n_cols;
        n_cols = cData.size();
    }

void SparseMatrix::print() const{
        for (int i = 0; i < n_rows; ++i){
            for (int j = 0; j < n_cols; ++j){
                if (cData[j].empty())
                    {std::cout << " 0";}
                else if (std::binary_search(cData[j].begin(), cData[j].end(), i))//Assumes row indices
                    {std::cout << " 1";}                                        //are ordered
                else
                    {std::cout << " 0";}
                if (n_cols-1 == j)
                    {std::cout << " \n";}
            }
        }
    }

void SparseMatrix::save(std::string path){
        std::fstream f_out;
        f_out.open(path, std::ios::out);
        if(f_out.is_open()){
            f_out << n_rows << "\n";
            f_out << n_cols << "\n";
            for(int j = 0; j < n_cols; ++j){
                int col_j_sz = cData[j].size();
                f_out << col_j_sz;
                for(int i = 0; i < col_j_sz; ++i){
                    f_out << " " << cData[j][i];
                }
                f_out << "\n";
            }
            f_out.close();
        }
        else{
            throw std::runtime_error("File did not open.");
        }
    }

bool matching_pivots(const SparseMatrix& a, const SparseMatrix& b){
    if(a.n_rows != b.n_rows || a.n_cols != b.n_cols){
        throw std::invalid_argument("Input matrices must have the same size.");
    }

    for (int j = 0; j<a.n_cols; ++j){
        bool a_j_empty = a.cData[j].empty();
        bool b_j_empty = b.cData[j].empty();
        if (a_j_empty != b_j_empty){
            return false;
        }
        else if (!a_j_empty){
            if(a.cData[j].back() != b.cData[j].back()){
                return false;
            }
        }
    }
    return true;
}

} // namespace ph_computation

Get the two char values from the string pointer array

We have to write a function to a program that receives a pointer to a string array which we populated with a text file. We now have to get the year the person was born from their ID by not using any built in functions or using the brackets.

void displayYearsBorn(string *pointerArr, int num){
    cout << "List of years born" << endl << endl;

    char d1, d2, year;

    for (int i = 0; i < num; i++){
        if ((*(pointerArr + i) == '_')){
            d1 = (*(pointerArr + i + 1) - '0') * 10;
            d2 = (*(pointerArr + i + 1) - '0');

            cout << (*(pointerArr + i + 1) - '0') << endl;
        }
    }
}

The lecturer we have gave us the for loop as a hint but, it does not work. I just want to know if anybody would be able to help.

Why does top of priority queue returns the wrong reference? If I remove the reference symbol from "auto& node" then it works as expected?

With the following code, it runs in a infinite loop, because in the second loop, the priority queue's top function still returns the old top, rather than the new top. I have to access the correct top by removing the reference symbol. How does it happen?

My compiling environment is Visual studio 2022.

#include <iostream>
#include <queue>

struct ListNode {
    int val;
    ListNode* next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode* next) : val(x), next(next) {}
    
};

using namespace std;


int main()
{
    ListNode* n1 = new ListNode(1);
    ListNode* n4 = new ListNode(4);
    vector<ListNode*> lists{ n1
        , n4 
    };

    priority_queue<ListNode*> q;
    for (auto n : lists) {
        q.push(n);
    }
    ListNode* pre = new ListNode(-1);
    auto tmp = pre;

    while (not q.empty()) {
       // will execute correctly if remove &
        auto& node = q.top();
        q.pop();
        tmp->next = node;

        if (node->next) {
            q.push(node->next);
        }

        tmp = tmp->next;
    }
    
}

dimanche 23 octobre 2022

Warning in visual studio in simple sfinae code

I am writing a simple code for learning sfinae. However, it generates a warning only in Visual Studio (not when using g++).

The code is:

#include <iostream>
#include <type_traits>

template <class T, typename std::enable_if<std::is_integral<T>::value, nullptr_t>::type = nullptr>
void f(T t)
{
    std::cout << "Integer" << std::endl;
    return;
}

template <class T, typename std::enable_if<!std::is_integral<T>::value, nullptr_t>::type = nullptr>
void f(T t)
{
    std::cout << "not integer" << std::endl;
    return;
}


int main()
{
    f(10);
    f(5.5);
    f("Hello");

    return 0;
}

And the warning is:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\ostream(746): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
sfinae2.cpp(9): note: see reference to function template instantiation 'std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char *)' being compiled
sfinae2.cpp(23): note: see reference to function template instantiation 'void f<int,nullptr>(T)' being compiled
        with
        [
            T=int
        ]                                                       

The warning disappears when compiling with the flag /EHsc, or when deleting the cout from both functions.

I want to know why this flag is needed.

Best regards.

samedi 22 octobre 2022

How to correctly access members of custom data types of C++ class?

I have wrote the following code.. My expected output is [4,11, 22, 33,44, 45, 46]

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <span>

/// FuntionMango class.
class FuntionMango
{
public:
    /// Getter of param types.
    const std::vector<uint8_t> &getParamTypes() const noexcept
    {
        return ParamTypes;
    }
    std::vector<uint8_t> &getParamTypes() noexcept { return ParamTypes; }

    /// Getter of return types.
    const std::vector<uint8_t> &getReturnTypes() const noexcept
    {
        return ReturnTypes;
    }
    std::vector<uint8_t> &getReturnTypes() noexcept { return ReturnTypes; }

private:
    /// \name Data of FuntionMango.

    std::vector<uint8_t> ParamTypes{11, 22, 33};

    std::vector<uint8_t> ReturnTypes{44, 45, 46};
};

// MangoType Class
class MangoType
{
    
public:
    /// Getter of content vector.

    std::vector<FuntionMango> &getContent() noexcept { return Content; }

private:
    /// \name Data of MangoType.

    std::vector<FuntionMango> Content;
};

// ValType Class

class Mango
{
public:
    const std::vector<MangoType> &getMangoType() const { return typeMan; }
    std::vector<MangoType> &getMangoType() { return typeMan; }

private:
    // There are many members of different types : I just mention one.
    std::vector<MangoType> typeMan;
};

std::vector<uint8_t> encoded(Mango &Man)
{
    std::vector<uint8_t> sok;
    std::vector<uint8_t> sap;
    for (int i = 0; i < Man.getMangoType().size(); i++)
    {
        for (int j = 0; j < Man.getMangoType()[i].getContent().size(); j++)
        {
            std::vector<uint8_t> saam = Man.getMangoType()[i].getContent()[j].getParamTypes();
            sok.insert(sok.end(), saam.begin(), saam.end());
            std::vector<uint8_t> sss = Man.getMangoType()[i].getContent()[j].getReturnTypes();
            sap.insert(sap.end(), sss.begin(), sss.end());
        }
    }

    std::vector<uint8_t> so;

    so.insert(so.end(), sok.begin(), sok.end());
    so.insert(so.end(), sap.begin(), sap.end());

    std::vector<uint8_t> result;

    result.push_back(4);
    result.insert(result.end(), so.begin(), so.end());

    return result;
}

std::vector<uint8_t> serial(Mango &Man)
{
    std::vector<uint8_t> s = encoded(Man);

    std::vector<uint8_t> ss;

    ss.insert(ss.end(), s.begin(), s.end());

    return ss;
}

int main()
{
    Mango Man; //Mango class object
    std::vector<uint8_t> seri = serial(Man);

    for (int i = 0; i < seri.size(); i++)
    {
        std::cout << unsigned(seri[i]) << " ";
    }
}

I'm not able to find the bug in this code. Currently I am getting the output [4] while my expected output [4,11, 22, 33,44, 45, 46]. Can someone show me the correct way of getting the above output by creating the object of Mango Class only?

How to create a template that can use different arguments from the same base class

I'm trying to create a Threshold template class that allows me to compare numeric values against a threshold value. I want to easily change the comparison function to use greater_equal or less_equal so I create the following template:

template<typename T, typename comp_func = std::greater_equal<T>, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
class Threshold
{
public:
    Threshold(T threasholdValue) : _thresholdValue(threasholdValue) {}
    ~Threshold() = default;

    bool isExceeded(T value) const
    {
        return comp_func{}(value, _thresholdValue);
    }

private:
    T _thresholdValue;
};

I want to be able to pass instances of this class to a function that accepts the Threshold:

template<typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
void foo(Threshold<T>& threshold)
{
. . .
}

This works fine as long as I use the default comparison function (std::greater_equal) but when I try to create a Threashold with "std::less_equal", this becomes a different type and I cannot pass it into foo:

Threshold<int32_t> greaterEqThreshold(5);
Threshold<int32_t, std::less_equal<int32_t>> lessEqThreshold(10);

foo(greaterEqThreshold);
foo(lessEqThreshold);  <--- Compile Error!

I understand why this is happening but I can't figure out how to solve the problem, other by creating a pure virtual class and having Threshold inherit from it and then using reference to that class. However, this solutions seems a little long winded for what I want do do.

Is there a way to make this work? Is there a better way to do this?

get the pid_t from std::thread::native_handle on Android?

For NDK api version >=21, there is pthread_gettid_np to convert pthread_t to pid_t. Is there any method to do this with older version api?

vendredi 21 octobre 2022

How can I print the exact type of variables in c++? [duplicate]

What I know:

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

int main()  
{    
    int a = 3;
    const int& b = 4;
    cout<<typeid(a).name()<<endl;
    cout<<typeid(b).name()<<endl;
}

So this 👆🏽 will going to print:

i    // i stands for int
i    

But my question is what can I do to print the exact type of b?

This is what I tried :

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

int main()  
{    
    int a = 3;
    const int& b = 4;
    cout<<typeid(a).name()<<endl;
    cout<<typeid(b).name()<<endl;
    
    decltype(b) k = 4;
    cout<<typeid(k).name()<<endl;
    return 0;
}

but still, output is :

i
i
i

Declaring a variable and assigning with move assignment operator in one statement on Clang causes seg fault

I've got this trivial example of what I thought was calling the move assignment operator of this Test struct. Running it, it calls the move constructor and then seg faults on destruction on Clang. On MSVC, it works fine.

I'm a bit confused by that behavior cause i would expect it to construct with the parameterless constructor and then call the move assignment operator.

#include <iostream>

struct Test
{
Test() : data(nullptr), dataCount(0) {}

Test(Test&& other)
{
  std::cout << "mv cstr" << std::endl << std::flush;
  delete[] data;
  data = other.data;
  other.data = nullptr;

  dataCount = other.dataCount;
}

Test& operator=(Test&& other)
{
  std::cout << "mv op" << std::endl << std::flush;
  
  delete[] data;
  data = other.data;
  other.data = nullptr;

  dataCount = other.dataCount;
  return *this;
}

~Test()
{
  std::cout << "dstr " << (void*)this << std::endl << std::flush; 
  delete[] data;
  data = nullptr;
}

char* data;
size_t dataCount;
};

int main() {
    Test test;
    test.data = new char[3];
    test.dataCount = 3;

    Test newTest = std::move(test);
    return 0;
}

If I instead declare and then assign, it of course works as expected

int main() {
    Test test;
    test.data = new char[3];
    test.dataCount = 3;

    Test newTest;
    newTest = std::move(test);
    return 0;
}

I've read through the std::move, move assignment operator, and move constructor documentation a few times but I'm just not getting what's specifically different here or left up to the compilers that would give different behavior between MSVC and Clang.

What am I missing?

Why does an argument type of std::set accept {} as argumet but boost::container::flat_set does not?

I converted some methods from argument type const std::set<>& to const boost::container::flat_set<>& with the same template types being passed. Now I have to change every occurrence of calls to these methods where the argument was {} and have to replace them with typename().

Why is this and is there some easier way?

boost_1_60_0 being used -- don't blame me!

To compile

g++ -std=c++11 test_set.cpp -D__FLAT__

or

g++ -std=c++11 test_set.cpp

The error message is clear -- and I couldn't read the original.

I guess the {} can only be interpreted as argument list, as the type is unknown.

#include <set>
#include <map>
#include <boost/container/flat_set.hpp>
#include <boost/container/flat_map.hpp>

#ifndef __FLAT__
typedef std::map<int, int> MAP;
typedef std::set<MAP> SET;
#else
typedef boost::container::flat_map<int, int> MAP;
typedef boost::container::flat_set<MAP> SET;
#endif


static void show(const SET&)
{
}
int main(int, char**)
{   

    //SET s({});
    show({});
}

example:

timer for measuring function execution time not working

I'm writing a cuda library and I need to check the differences in performance between the option CPU and GPU. So I created a simple class called Timer to measure the time required to execute first a GPU function and then the CPU version.

class Timer
{
public:
    Timer()
    {
        _StartTimepoint = std::chrono::steady_clock::now();
    }
 
    ~Timer() {}

    void Stop()
    {

        _stopped = true;
        using namespace std::chrono;
        auto endTimepoint = steady_clock::now();

        auto start = time_point_cast<milliseconds>(_StartTimepoint).time_since_epoch().count();
        auto end = time_point_cast<milliseconds>(endTimepoint).time_since_epoch().count();

        auto _ms = end - start;



        _secs   = _ms   / 1000;
        _ms    -= _secs * 1000;
        _mins   = _secs / 60;
        _secs  -= _mins * 60;
        _hour   = _mins / 60;
        _mins  -= _hour * 60;


    }


    double GetTime(){
        if(_stopped == true)
            return _ms;
        else{
            Stop();
            return _ms;
        }
    }

private:
    std::chrono::time_point< std::chrono::steady_clock> _StartTimepoint;
    double _secs,_ms,_mins,_hour;
    bool _stopped = false;
};

Since I need to check the performances for different values of a parameter m I just run both the functions inside a for loop as you can see:

for (size_t m = MIN_M; m < MAX_M; m+=M_STEP){
        m_array[m_cont] = m;
        //simulate
        double time_gpu,time_cpu;

        Timer timer_gpu;
        run_device(prcr_args,seeds,&m_array[m_cont]);
        timer_gpu.Stop();
        time_gpu = timer_gpu.GetTime();

        Timer timer_cpu;
        simulate_host(prcr_args,seeds,&m_array[m_cont]);
        timer_cpu.Stop();
        time_cpu = timer_cpu.GetTime();
        
        double g = time_cpu/time_gpu;
        
        ofs << m  //stream to print the results
            << "," << time_cpu
            << "," << time_gpu 
            << "," << g << "\n";
        m_cont ++;
    }

The problem is that the results i obtain are incredibly small and clearly wrong since they all are equal (the execution time should increase with m) and that my code requires a couple of minutes to run.

m,cpu_time,gpu_time,g
10,9.88131e-324,6.90979e-310,1.43004e-14
15,9.88131e-324,6.90979e-310,1.43004e-14
....
90,9.88131e-324,6.90979e-310,1.43004e-14
95,9.88131e-324,6.90979e-310,1.43004e-14
100,9.88131e-324,6.90979e-310,1.43004e-14

My guess is that the CPU doesn't execute the cycle sequentially and therefore starts and stops the clock immediately.

How to erase specific index of std::vector of std::pair?

I have a std::vector of std::pair of std::string where the language and translation are the values. These are values in my vector of pair

 0. {English, Love},  
 1. {Spanish, Amor},  
 2. {Tagalog, Mahal},  
 3. {English, Love}

What I wanted to do is to only remove the index 3, but in my code if I try to remove the index 3, both index 0 and 3 are removed.

Here's my code:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <utility>

auto main() -> int {

  using pair_of = std::vector<std::pair<std::string, std::string>>;

  pair_of language_translation{};

  language_translation.emplace_back(std::make_pair("English", "Love"));
  language_translation.emplace_back(std::make_pair("Spanish", "Amor"));
  language_translation.emplace_back(std::make_pair("Tagalog", "Mahal"));
  language_translation.emplace_back(std::make_pair("English", "Love"));

  std::string language = "English";
  std::string translation = "Love";

  auto selected_pair = std::remove_if(
    language_translation.begin(), language_translation.end(),
    [&](const std::pair<std::string, std::string> &data_pair) {
      if(data_pair.first == language && data_pair.second == translation) {
        return true; 
      }
      else {
        return false;
      }
    }
  );
  
  language_translation.erase(selected_pair, language_translation.end());
  
  for(const auto &pair : language_translation) {
    std::cout << pair.first << ": " << pair.second << std::endl;
  }

}

The output result is

Tagalog: Mahal
Spanish: Amor

What other algorithm can I use to solve a problem like this? Can you guys give an example? Thank you!

jeudi 20 octobre 2022

Returning std::vector<:unique_ptr>> from function

I'm trying to return a vector of unique_ptrs from a function, but I'm running into errors (MSVC 19.33.31630).

The comments to this question recommend returning by value, but

std::vector<std::unique_ptr<int>> test1()
{
    std::vector<std::unique_ptr<int>> ret = { std::make_unique<int>(1) };
    return ret;
}

int main()
{
    std::vector<std::unique_ptr<int>> x = test1();
    std::unique_ptr<int>& ptrY = x.at(0);
    return 0;
}

yields the error Error C2280 'std::unique_ptr<int,std::default_delete>::unique_ptr(const std::unique_ptr<int,std::default_delete> &)': attempting to reference a deleted function

Returning by reference, as in

std::vector<std::unique_ptr<int>>& test2()
{
    std::vector<std::unique_ptr<int>> ret = { std::make_unique<int>(1) };
    return ret;
}

int main()
{
    std::vector<std::unique_ptr<int>>& y = test2();
    std::cout << *(y.at(0)) << std::endl; 

    return 0;
}

yields the same error.

Why is this happening? Is the ownership of the unique_ptr not transferring properly? Any help would be greatly appreciated.

Operator Overloading with polymorphism abstract class c++

I cannot make operator overloading work, and i don't have the clarity why and i want to understand better what is happening.

I got this code:

figure.h

class Figure {
public:
    explicit Figure();
    virtual ~Figure();
    virtual double calculateArea() = 0;

    virtual double getWidth() const;
    virtual void setWidth(double newWidth);

    virtual double getHeight() const;
    virtual void setHeight(double newHeight);

    virtual double getArea() const;
    virtual void setArea(double newArea);

protected:
    double width;
    double height;
    double area;
};

square.h

class Square : public Figure {
public:
    Square( double width, double height );
    virtual ~Square();
    double calculateArea();

    void operator<(Square &f)  {
        cout << "test";
        return this->area > f.area;
    }
};

square.cpp

Square::Square( double _width, double _height ) : Figure() {
    width = _width;
    height = _height;
    area = calcularArea();
}

Square::~Square() {}

double Square::calculateArea() {
    return (width * height);
}

main.cpp

int main() {

    Figure *f1 = new Square(10, 20);
    Figure *f2 = new Square(20, 30);

    if (f1 < f2)  {
        cout << "f1 is bigger than f2";
    } else {
        cout << "f2 is bigger than f1";
    }

    return 0;
}

the result:

  • the cout "test" does not log to the console
  • the operator overloading not working

i tried many things with pointers and function parameters, even moved the operator overload to the Figure class and still not working.

I want to understand WHY and WHAT is happening, and how can i make it work.

Thanks

What does " [&]() " mean in C++?

I am reading to an open source project. I am not able to understand what this snippet does ?

EXPORT Result LoaderParse(
    LoaderContext *Cxt, Context **Module,
    const char *Path) {
  return wrap(
      [&]() {
        return fromloa(Cxt)->parse(std::filesystem::absolute(Path));
      },
      [&](auto &&Res) { *Mod = toAST((*Res).release()); }, Cxt,
      Module);
}


template <typename T, typename U, typename... CxtT>
inline Result wrap(T &&Proc, U &&Then, CxtT *...Cxts) noexcept {
  if (isC(Cxts...)) {
    if (auto Res = Proc()) {
      Then(Res);
      return 0;
    } else {
      return 1;
    }
  } else {
    return 2;
  }
}

Can anyone explain me what does [&] do in this case?

Producer consumer probelm c++ [closed]

This code is for Consumer Producer problem so i created Buffer class which is contain an array to store the data then i create two method one for conumer and producer the problem is when i want to deal with the thread i faced the error which is (argument of type "void *" is incompatible with parameter of type "void ()(void *)") i did understand it what i should to do! , Can any one help me please ?

#include <unistd.h>
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include <stdlib.h>
#include<thread>
using namespace std;
#define BUFFER_CAPACITY 10
sem_t Empty;
sem_t Full; 
pthread_mutex_t mutex;
class Buffer {
    int buffer [BUFFER_CAPACITY];
    int produced_index; // index
    int consumed_index; // index
public:
Buffer(){
    this->consumed_index=0;
    this->produced_index=0;}    
    void *producer(void *pno){ // to produce data to the buffer []
        srand(time(NULL));
         int item;
         while(true){
            item = 1 + rand() % 100;
            sem_wait(&Empty);
            pthread_mutex_lock(&mutex);
            usleep(50000 * 10);
            buffer[produced_index] = item;
            cout << "Producer " << *((int *)pno)<< ": Insert Item " << buffer[produced_index] << " at " << produced_index << endl;
            produced_index = (produced_index + 1) % BUFFER_CAPACITY; 
            pthread_mutex_unlock(&mutex);
            sem_post(&Full);}
    void* VOID;
    return VOID;
    }
    void *counsumer(void *pno){ // to take the data from the buffer
        
        while(true){
            sem_wait(&Full);
            pthread_mutex_lock(&mutex);
            usleep(100000 * 10);
            int item = buffer[consumed_index];
            cout << "Consumer " << this->id << ": Remove Item " << item << " from " << consumed_index << endl;
            consumed_index = (consumed_index + 1) % BUFFER_CAPACITY;
            pthread_mutex_unlock(&mutex);
            sem_post(&Empty);
        }
    void* VOID;
    return VOID;}};
int main(){
    Buffer buf; // Create buffer
    pthread_mutex_init(&mutex, NULL);
    sem_init(&Empty,0,BUFFER_CAPACITY);
    sem_init(&Full,0,0);
    pthread_t pro[5],con[5];
    int a[5] = { 1, 2, 3, 4, 5 };
    for(int i = 0; i < 5; i++) pthread_create(&pro[i], NULL, buf.producer(), (void *)&a[i]); 
    for(int i = 0; i < 5; i++){ pthread_create(&con[i], NULL, buf.counsumer(), (void *)&a[i]); }
    for(int i = 0; i < 5; i++){ pthread_join(pro[i], NULL); }
    for(int i = 0; i < 5; i++){ pthread_join(con[i], NULL); }
  pthread_mutex_destroy(&mutex);
        sem_destroy(&Empty);
    sem_destroy(&Full);}

so can any one help me to dealing with synchronization

std::regex_match not matching the whole string?

I have encountered a problem with the regular expression I was using and after some testing got to the point where I found that (.+) was not matching everything, but only the first token of the string. I have found nothing that helps me so far and no explanation as to why this is happening, much less how to fix it so if anyone knows what is going on, just PLEASE explain it to me.

c++ explicit referencing and upcasting [closed]

I know, in c++, I can get the reference of an object by saying

A a{12};
A &ra = a;

To make this a little explicit I can say

A a{12};
A &ra = (A&)a;

But what does the following do?

A a{12};
(A)a;

Imagine I have a class hierarchy

Base base{ /* */}
Derived derived : public Base{ /* */}

Derived dd;
Base &bb = dd; // I know this is okay
// Base &bb = (Base&) dd; // I can use this one to make it explicit but
// Base &bb = (Base)dd; // what's up with that?

Undefined reference to `FastPForLib:..' while linking FastPForlib

Any suggestion regarding the following query would be appreciated. I have tried everything and am still struck with this error. The library (FastPFor) works fine with the visual studio solution; the issue arises when I try to use it with my project containing the file (src/example.cpp).

I am trying to link the static library (lib/FastPFor/libFastPFOR.a) to my example.cpp. I have copied the header files in the (include/FastPFor/*h) while I obtained FastPForlib.a by running the CMake command followed by make, on Ubuntu run via WSL.

Following is my dependency-tree

example (proj)
include
------------>FastPFor
--------------------->*h
lib
------------>FastPFor
--------------------->liblibFastPFor.a
src
------------>example.src
Makefile

Following is my makefile:

.SUFFIXES:
#
.SUFFIXES: .cpp .o .c .h
LDFLAGS = -Llib/FastPFor -llibFastPFOR
# replace the CXX variable with a path to a C++11 compatible compiler.
# to build an aligned version, add -DUSE_ALIGNED=1
ifeq ($(INTEL), 1)
# if you wish to use the Intel compiler, please do "make INTEL=1".
    CXX ?= /opt/intel/bin/icpc
    CC ?= /opt/intel/bin/icpc
ifeq ($(DEBUG),1)
    CXXFLAGS = -fpic -std=c++11 -O3 -Wall -ansi -xAVX -DDEBUG=1 -D_GLIBCXX_DEBUG -ggdb 
    CCFLAGS = -fpic -std=c99 -O3 -Wall  -ansi -xAVX -DDEBUG=1 -D_GLIBCXX_DEBUG -ggdb 
else
    CXXFLAGS = -fpic -std=c++11 -O2 -Wall  -ansi -xAVX -DNDEBUG=1  -ggdb 
    CCFLAGS = -fpic -std=c99 -O2 -Wall   -ansi -xAVX -DNDEBUG=1  -ggdb 
endif # debug
else #intel
    CXX ?= g++-4.7
ifeq ($(DEBUG),1)
    CXXFLAGS = -fpic -mavx -std=c++11  -Weffc++ -pedantic -ggdb -DDEBUG=1 -D_GLIBCXX_DEBUG -Wall  -Wextra -Wextra -Wsign-compare  -Wwrite-strings -Wpointer-arith -Winit-self  -Wno-sign-conversion
    CCFLAGS = -fpic -mavx -std=c99  -pedantic -ggdb -DDEBUG=1 -D_GLIBCXX_DEBUG -Wall  -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith -Winit-self  -Wno-sign-conversion 
else
    CXXFLAGS = -fpic -mavx -std=c++11  -Weffc++ -pedantic -O3 -Wall  -Wextra -Wsign-compare  -Wwrite-strings -Wpointer-arith -Winit-self  -Wno-sign-conversion 
    CCFLAGS = -fpic -mavx -std=c99 -pedantic -O3 -Wall -Wextra -Wsign-compare -Wwrite-strings -Wpointer-arith -Winit-self -Wno-sign-conversion 
endif #debug
endif #intel


HEADERS= $(shell ls include/FastPFor/*.h)

all: example


example: $(HEADERS) src/example.cpp
    $(CXX) $(CXXFLAGS) -o example $(LDFLAGS) src/example.cpp 

clean:
    rm -f *.o example

astyle:
    astyle --options=astyle.conf --recursive "*.cpp" "*.h"

.PHONY: all clean astyle

Running make produced bunch of errors, all related to undefined reference to FastPFOR. It looks something like following:

/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x781): undefined reference to `__fastunpack11(unsigned int const*, unsigned long*)'
/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x791): undefined reference to `__fastunpack10(unsigned int const*, unsigned long*)'
/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x7a1): undefined reference to `__fastunpack9(unsigned int const*, unsigned long*)'
/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x7b1): undefined reference to `__fastunpack4(unsigned int const*, unsigned long*)'
/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x7c1): undefined reference to `__fastunpack3(unsigned int const*, unsigned long*)'
/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x7d1): undefined reference to `__fastunpack64(unsigned int const*, unsigned long*)'
/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x7e1): undefined reference to `__fastunpack8(unsigned int const*, unsigned long*)'
/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x7f1): undefined reference to `__fastunpack7(unsigned int const*, unsigned long*)'
/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x801): undefined reference to `__fastunpack6(unsigned int const*, unsigned long*)'
/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x811): undefined reference to `__fastunpack5(unsigned int const*, unsigned long*)'
/usr/bin/ld: example.cpp:(.text._ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm[_ZN11FastPForLib12FastPForImplILj8EmE13__decodeArrayEPKjRmPmm]+0x87c): undefined reference to `__fastunpack2(unsigned int const*, unsigned long*)'
collect2: error: ld returned 1 exit status
make: *** [Makefile:36: example] Error 1

Thank you in advance.

unit test c++ no matter what kind of environment I execute [closed]

if I want to write unit test code to test my c++ code, I want to write unit test c++ no matter what kind of environment I execute, because I sometimes write code on vsCode, and sometimes on onlineGdb.

mercredi 19 octobre 2022

Attaching a Comment to a YAML::Node for Presentation in Output

I'm using yaml-cpp with C++11. I can create a YAML file using something simple like this:

#include <yaml-cpp/yaml.h>
#include <iostream>

int main(void)
{
  YAML::Node  topNode;

  topNode["one"]["two"]["A"] = "foo";
  topNode["one"]["two"]["B"] = 42;

  std::cout << "%YAML 1.2\n---\n" << topNode;
  return 0;
}

That will produce a YAML file like this:

%YAML 1.2
---
one:
  two:
    A: foo
    B: 42

Lovely!

I can also produce exactly the same YAML file like this:

#include <yaml-cpp/yaml.h>
#include <iostream>

int main(void)
{
  YAML::Emitter  out;

  out << YAML::BeginMap // document {
      << "one"
        << YAML::BeginMap // one {
        << "two"
          << YAML::BeginMap // two {
          << YAML::Key << "A" << YAML::Value << "foo"
          << YAML::Key << "B" << YAML::Value << 42
          << YAML::EndMap // two }
        << YAML::EndMap // one }
      << YAML::EndMap // document }
      ;

  std::cout << "%YAML 1.2\n---\n"
            << out.c_str();
  return 0;
}

The nice thing about the second approach is that I can also add comments into the output file:

#include <yaml-cpp/yaml.h>
#include <iostream>

int main(void)
{
  YAML::Emitter  out;

  out << YAML::BeginMap // document {
      << "one"
        << YAML::BeginMap // one {
        << "two"
          << YAML::BeginMap // two {
          << YAML::Key << "A" << YAML::Value << "foo"
             << YAML::Comment("A should be 'foo'")
          << YAML::Key << "B" << YAML::Value << 42
             << YAML::Comment("B is meaningful")
          << YAML::EndMap // two }
        << YAML::EndMap // one }
      << YAML::EndMap // document }
      ;

  std::cout << "%YAML 1.2\n---\n"
            << out.c_str();
  return 0;
}

to produce:

%YAML 1.2
---
one:
  two:
    A: foo  # A should be 'foo'
    B: 42  # B is meaningful

My question if there is a way to add comments into the first approach? Perhaps something like this:

  topNode["one"]["two"]["A"] = "foo";
  topNode["one"]["two"]["A"].addComment("A should be 'foo'");

I could subclass YAML::Node, adding my addComment() method, but I don't want to re-write all of YAML::Emitter to get my comment appended appropriately. The code is there, but I don't know how to get to it. How? Can you point me to an example or an approach?

I understand that the YAML specification says that comments are not an integral part of a YAML file, and can be discarded. My users find them useful, so I don't relish a debate that begins with "Your question is stupid." :-)

Trigger an event in C# node from native C++ code

class SimpleCamera
{
private:
    ImagePtr* image
    std::mutex lock;
public:
    void StartGrabing();
    void OnImageGrabbed(ImagePtr* frame); //EventHandler Function
};

void SimpleCamera::OnImageGrabbed(ImagePtr* frame)
{
    mLock.lock();
    image = frame;
    mLock.unlock();
    //Fire the managed/C# event
}

The OnImageGrabbed is event handler function which is called each time frame is available. I am supposed to use this frame to display an image on GUI which is written in C#. However, the restriction from camera vendor is that I cannot access UI objects in this function.

The way I was planning to display an image on C# GUI is that I would like to trigger an event in C# code from within OnImageGrabbed() function(native C++ code) which will in turn access the ImagePtr in C++, copy the data over and display on the C# GUI. I have the copying the data over figured out but not triggering the event.

How can I do this?

Raw string literals won't compile on macOS? [duplicate]

For some reason, the code compiles on Windows but not on macOS. The issue appears to be a raw string literal that I was using so that I could write a multi-line string.

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string test = R"(
        This is a 
        test string.
    )";
    cout << test << endl;
}

I get the following error after attempting to run this file:

error: use of undeclared identifier 'R'
    string test = R"(

c++ pass a curried function to a function which receives a pointer [duplicate]

void foo(void (*)(long v)) {}

auto makeBar(long baz) {
    return [=](long v) {
        std::cout << "hello from closure " << baz;
    };
}


int main() {
   auto  bar = makeBar(2);
   foo(bar);
   return 0;
}

Hi,

I'm trying to do the above. Essentially create a curried function makeBar which receives a parameter baz. then instantiate it and pass the result to function foo.

the following does not compile. Specifically the call to foo(bar). If I remove the capture [=] it compiles, but then I can't use baz within the curry.

How can this be done?

Can `>>` operator be overloaded to able to `std::cin >> function(with_param)` in C++?

I was wondering if it is possible if I can overload the >> operator?

For example in code. If I have this function that capitalize the first letter of std::string

auto capitalize_first_letter(std::string &text) -> void { 
  text[0] = toupper(text[0]); 
}

How can I do something like this

std::string word{};
std::cin >> capitalize_first_letter(word);

Is this possible?

How can I pass array to LLVM IR Function arguments and get value by index

I want to pass an array to LLVM IR Function, and get value by index. The code as follows, but it dont't work.


  Function *FooF =
      Function::Create(FunctionType::get(Type::getInt32Ty(Context), {ArrayType::getInt32PtrTy(Context), Type::getInt32Ty(Context)}, false),
                       Function::ExternalLinkage, "foo", M);
  // Add a basic block to the FooF function.
  BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", FooF);
  IRBuilder<> builder(BB);
  // Get pointer to array
  Value *arg1 = FooF->arg_begin();
  // Get index
  Value *index = arg1+1;
  // Get first_element
  Value *first_element = builder.CreateExtractElement(arg1, index);
  builder.CreateRet(first_element);

  // Now we create the JIT.
  ExecutionEngine* EE = EngineBuilder(std::move(Owner)).create();
  using FunctionPtr = int(*)(int32_t *, int);
  FunctionPtr func = reinterpret_cast<FunctionPtr>(EE->getFunctionAddress("foo")) ;
  int32_t array[3] = {1,2,3};
  int first = func(array, 0);

}

__FUNCSIG__ with MSVC for variadic template

If I run the following code with MSVC ...

#include <iostream>

using namespace std;

struct S {};

template<typename ... Args>
void variadic( Args &&... args )
{
    cout << __FUNCSIG__ << endl;
}

int main()
{
    S s;
    variadic( (S &)s, (S const &)s, (S &&)s, (S const &&)s );
}

... the code prints (re-formatted) ...

void variadic<struct S&,const struct S&,struct S,const struct S>(
    struct S &,const struct S &,struct S &&,const struct S &&)

Why has the parameter-list the proper reference-types I specified while calling variadic and the specialization inside <> doesn't have the proper types for r-value references ?

mardi 18 octobre 2022

How to delete an array that is in a struct inside a struct c++

This is for an assignment for one of my classes and I am stuck, I have to use these required structs, those being:

struct Pokemon {
    int dex_num;
    string name;
    string type;
    int num_moves;
    string* moves;
};

struct Pokedex {
    string trainer;
    int num_pokemon;
    Pokemon* dex;
};

I was tasked to create an array of pokemon with the available information from a .txt file. I name the Pokedex struct "Pokedex data;" what I am stuck on is the erasing of said array

void delete_info(Pokedex &);

The function above this text is how I have to delete it, and I am confused I have tried

delete []data.dex;
data.dex = NULL;

I have tried to dereference it and I have tried

delete []dex;

delete []data; 

etc.

Every single one has led me into a seg fault, or just general bugs and declaration issues.

edit this is how I was supposed to allocate the memory

Pokemon * dex  =  create_pokemons(7);

this is what I called for in my main


Pokemon* create_pokemons(int y) {
    Pokemon* dex = new Pokemon[y];
    return dex;
} 

i'm not quite sure what went wrong.

edit I am not allowed to use vectors

Running code in one thread is slower than running the code in main thread

I'm testing running double calculations in a thread and I got this strange result. Running the calculations in the main thread takes almost half the time than running it in a separate thread and calling join in the main thread. If it's a single thread there shouldn't be a big difference from just running the function. Am I doing something wrong?

The cpu is Intel Xeon E-2136 limited at 4.1GHz to have the same boost frequency in independent of how many cores are running.

#include <cstdio>
#include <stdexcept>
#include <thread>
#include <future>
#include <malloc.h>
#include <time.h>

#define TEST_ITERATIONS 1000*1000*1000

void *testNN(void *dummy) {
  volatile double x;
  for (int i = 0; i < TEST_ITERATIONS; ++i) {
    x = rand();
    x *= rand();
  }
  return nullptr;
}

int main(){
    time_t start = time(nullptr);

    { // for future to join thread

      testNN(nullptr); // 12s

//      pthread_t thread_id;
//      pthread_create(&thread_id, NULL, testNN, nullptr);
//      pthread_join(thread_id, NULL); //27s

      std::future<void *> f[12];
//      f[0] = std::async(std::launch::async, testNN, nullptr);   // 27s
      // for multithreaded testing:
//    f[1] = std::async(std::launch::async, testNN, nullptr);
//    f[2] = std::async(std::launch::async, testNN, nullptr);
//    f[3] = std::async(std::launch::async, testNN, nullptr);
//    f[4] = std::async(std::launch::async, testNN, nullptr);
//    f[5] = std::async(std::launch::async, testNN, nullptr);
//    f[6] = std::async(std::launch::async, testNN, nullptr);
//    f[7] = std::async(std::launch::async, testNN, nullptr);
//    f[8] = std::async(std::launch::async, testNN, nullptr);
//    f[9] = std::async(std::launch::async, testNN, nullptr);
//    f[10] = std::async(std::launch::async, testNN, nullptr);
//    f[11] = std::async(std::launch::async, testNN, nullptr);

    }

    time_t runTime = time(nullptr);
    runTime -= start;

    printf("calc done in %lds (%ld calc/s)\n", runTime, TEST_ITERATIONS / runTime);

}

I compile with

# g++ -std=c++11 test.cpp  -o test -lpthread

and results for function call, pthread and std::async respectively:

# time ./test
calc done in 12s (83333333 calc/s)

real    0m12.073s
user    0m12.070s
sys     0m0.003s

# time ./test
calc done in 27s (37037037 calc/s)

real    0m26.741s
user    0m26.738s
sys     0m0.004s

# time ./test
calc done in 27s (37037037 calc/s)

real    0m26.788s
user    0m26.785s
sys     0m0.003s

lundi 17 octobre 2022

Is there any potential problem when returning a std::future from a local std::promise?

Here is the example code snippet:

#include<future>
#include<iostream>

int main()
{
    auto f=[](){
        std::promise<int> promise_;   //Since `promise_` is a local variable, is there any potential problem?
        auto future_ = promise_.get_future();
        promise_.set_value(1);

        return future_;
    }();

    std::cout << f.get() << std::endl;
}

Undefined Behavior in Unions with Standard Layout structs

Take the following code

union vec
{
    struct
    {
        float x, y, z;
    };

    float data[3];

    constexpr vec() : data{} {}
};

constexpr vec make_vec(float x, float y, float z)
{
    vec res;
    res.data[0] = x;
    res.data[1] = y;
    res.z = z;
    return res;
}

int main()
{
    constexpr vec out = make_vec(0, 1, 2);
    std::cout << out.z << '\n';
}

I make use of constexpr here to determine whether the code is undefined behavior or not, as the undefined behavior will cause a compilation error.

§9.2/19:

If a standard-layout union contains two or more standard-layout structs that share a common initial sequence, and if the standard-layout union object currently contains one of these standard-layout structs, it is permitted to inspect the common initial part of any of them.

From this, I would assume that everything in the code would be defined behavior.

Compiling with g++ main.cpp -o out -std=c++17, I get the message error: change of the active member of a union from 'vec::data' to 'vec::<anonymous>'.

I thought that to comply with the standard, I might've had to change it to this--

union vec
{
    struct
    {
        float x, y, z;
    };

    struct
    {
        float data[3];
    };

    constexpr vec() : data{} {}
};

But I get the same error.

Is this truly undefined behavior? Is there perhaps another part of the standard that I've missed, or am I simply misinterpreting the standard?

C++: Nested dictionaries with unordered_maps

I'm trying to write some code that will allow me to create a dictionary with the unordered_map object in C++. It will basically look like

string1
    string2
        int_vec1
    string3
        int_vec2
...

i.e. It's a dictionary of string and integer-vector pairs, indexed by strings.

I have the following code of a simplified example to illustrate:

#include <chrono>
#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <ctime>
#include <string>
#include <unordered_map>

int main(int argc, char **argv) {
  std::string key_0 = "key_0";
  std::string key_01 = "key_01";
  std::string key_02 = "key_02";
  std::string key_1 = "key_1";
  std::string key_11 = "key_11";
  std::string key_12 = "key_12";
  std::string key_13 = "key_13";
  std::vector<int> val_01 = {1,2,3,4};
  std::vector<int> val_02 = {1,2,3,4};
  std::vector<int> val_11 = {1,2,3,4};
  std::vector<int> val_12 = {1,2,3,4};
  std::vector<int> val_13 = {1,2,3,4};

  std::unordered_map<std::string, std::unordered_map<std::string, std::vector<int>>> my_dict;
  my_dict.insert({key_0, std::pair<std::string, std::vector<int>>(key_01, val_01)});

}

However, when I compile this using gcc version 11.2.0, I get the following error

test_make_nested_unordered_map.cpp:25:17: error: no matching function for call to ‘std::unordered_map<std::__cxx11::basic_string<char>, std::unordered_map<std::__cxx11::basic_string<char>, std::vector<int> > >::insert(<brace-enclosed initializer list>)’
   25 |   my_dict.insert({key_0, std::pair<std::string, std::vector<int>>(key_01, val_01)});
      |   ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The code seems fine to me. But I don't know why it isn't working. I would greatly appreciate some help with this. My actual code is more complicated, but this is just meant to be a simplified reproducible example.

Thanks for the help

dimanche 16 octobre 2022

Removing a callback function from a vector c++

I'm building a publish-subscribe class (called SystermInterface), which is responsible to receive updates from its instances, and publish them to subscribers.

Adding a subscriber callback function is trivial and has no issues, but removing it yields an error, because std::function<()> is not comparable in C++.

std::vector<std::function<void()> subs;
void subscribe(std::function<void()> f)
{
    subs.push_back(f);
}
void unsubscribe(std::function<void()> f)
{
    std::remove(subs.begin(), subs.end(), f);  // Error
}

I've came down to five solutions to this error:

  1. Registering the function using a weak_ptr, where the subscriber must keep the returned shared_ptr alive.
    Solution example at this link.
  2. Instead of registering at a vector, map the callback function by a custom key, unique per callback function.
    Solution example at this link
  3. Using vector of function pointers. Example
  4. Make the callback function comparable by utilizing the address.
  5. Use an interface class (parent class) to call a virtual function.
    In my design, all intended classes inherits a parent class called ServiceCore, So instead of registering a callback function, just register ServiceCore reference in the vector.

Given that the SystemInterface class has a field attribute per instance (ID) (Which is managed by ServiceCore, and supplied to SystemInterface by constructing a ServiceCore child instance).

To my perspective, the first solution is neat and would work, but it requires handling at subscribers, which is something I don't really prefer.

The second solution would make my implementation more complex, where my implementation looks as:

using namespace std;
enum INFO_SUB_IMPORTANCE : uint8_t
{
    INFO_SUB_PRIMARY,       // Only gets the important updates.
    INFO_SUB_COMPLEMENTARY, // Gets more.
    INFO_SUB_ALL            // Gets all updates
};

using CBF = function<void(string,string)>;
using INFO_SUBTREE = map<INFO_SUB_IMPORTANCE, vector<CBF>>;

using REQINF_SUBS   = map<string, INFO_SUBTREE>; // It's keyed by an iterator, explaining it goes out of the question scope.
using INFSRC_SUBS   = map<string, INFO_SUBTREE>;
using WILD_SUBS     = INFO_SUBTREE;

REQINF_SUBS infoSubrs;
INFSRC_SUBS sourceSubrs;
WILD_SUBS wildSubrs;

void subscribeInfo(string info, INFO_SUB_IMPORTANCE imp, CBF f) {
    infoSubrs[info][imp].push_back(f);
}
void subscribeSource(string source, INFO_SUB_IMPORTANCE imp, CBF f) { 
    sourceSubrs[source][imp].push_back(f);
}
void subscribeWild(INFO_SUB_IMPORTANCE imp, CBF f) {
    wildSubrs[imp].push_back(f);
}

The second solution would require INFO_SUBTREE to be an extended map, but can be keyed by an ID:

using KEY_T = uint32_t; // or string...
using INFO_SUBTREE = map<INFO_SUB_IMPORTANCE, map<KEY_T,CBF>>;

For the third solution, I'm not aware of the limitations given by using function pointers, and the consequences of the fourth solution.

The Fifth solution would eliminate the purpose of dealing with CBFs, but it'll be more complex at subscriber-side, where a subscriber is required to override the virtual function and so receives all updates at one place, in which further requires filteration of the message id and so direct the payload to the intended routines using multiple if/else blocks, which will increase by increasing subscriptions.

What I'm looking for is an advice for the best available option.

use enum in std::atomic::compare_exchange_strong()

I tried to use std::atomic::compare_exchange_strong() with enum but it raise this error

cannot bind non-const lvalue reference of type ‘std::__atomic_base<int>::__int_type&’ {aka ‘int&’} to an rvalue of type ‘std::__atomic_base<int>::__int_type’ {aka ‘int’}

here is part of my code, simplified for the key.

enum LockStatus
{
    readed, 
    reading,
    writing,
    written
};

int main()
{
    atomic_int **lock;
    lock=new atomic_int* [n];
    for(int i=0; i<n ;i++)
    {
        if(lock[i]->compare_exchange_strong(readed,writing))
        {
           //something to do 
        }
    }
}

I think this problem is caused by enum is a right value but compare_exchange_strong need a left value, if I define these LockStatus as int it will work,but I was wondering if there is a more elegant why to solve this problem?

Thank you for your answer!

samedi 15 octobre 2022

Is this an error in the Effective Modern C++ book?

Item 37 in the book illustrates an implementation of ThreadRAII, that either joins a thread or detaches it when it is destroyed. By declaring the destructor the compiler doesn’t generate the move operations, but in the book the author says that there’s no reason why they should not be movable and says that compilers would generate the right move operations and advises us to use the ‘= default’ implementation.

#include <thread>

class ThreadRAII
{
public:
    enum class DtorAction { join, detach };

    ThreadRAII(std::thread&& t, DtorAction a)
        : action(a)
        , t(std:: move(t))
    {}

    ~ThreadRAII()
    {
        if(t.joinable())
        {
            if(action == DtorAction::join)
                t.join();
            else
                t.detach();
        }
    }

    ThreadRAII(ThreadRAII&&) = default;

    ThreadRAII& operator=(ThreadRAII&&) = default;

    std::thread& get() { return t; }

private:
    DtorAction action;
    std::thread t;
};

int main()
{
    ThreadRAII t{std::thread{[]{}}, ThreadRAII::DtorAction::join};

    t = ThreadRAII{std::thread{[]{}}, ThreadRAII::DtorAction::detach};

    return 0;
}

But in the example above, std::terminate is called.

I think that the default move constructor should be ok, but not the move assignment, because the move assignment has to release the current resource before acquiring the new one. Otherwise, the assignment is going to destroy a thread that is joinable, which causes program termination.

I didn't see this issue in the errata list for the book. Is the book really wrong by saying the default move assignment operator should be fine? I would like to be sure and have other people look at it in order to contact the author.

This is what I think it should have been:

#include <thread>

class ThreadRAII
{
public:
    enum class DtorAction { join, detach };

    ThreadRAII(std::thread&& t, DtorAction a)
        : action(a)
        , t(std:: move(t))
    {}

    ~ThreadRAII()
    {
        release();
    }

    ThreadRAII(ThreadRAII&&) = default;

    ThreadRAII& operator=(ThreadRAII&& rhs)
    {
        release();
        action = rhs.action; 
        t = std::move(rhs.t);
        return *this;
    }

    std::thread& get() { return t; }

    void release()
    {
        if(t.joinable())
        {
            if(action == DtorAction::join)
                t.join();
            else
                t.detach();
        }
    }

private:
    DtorAction action;
    std::thread t;
};

int main()
{
    ThreadRAII t{std::thread{[]{}}, ThreadRAII::DtorAction::join};

    t = ThreadRAII{std::thread{[]{}}, ThreadRAII::DtorAction::detach};

    return 0;
}

WIL Wrappers for Private Namespaces and Boundary Descriptors

I am currently reading "Windows 10 System Programming" by Pavel Yosifovich. Since The WIL Library doesn't have a boundary descriptor and private namespace wrapper, he creates it:

namespace wil {
    static void close_private_ns(HANDLE h) {
        ::ClosePrivateNamespace(h, 0);
    };

    using unique_private_ns = unique_any_handle_null_only<decltype(&close_private_ns), close_private_ns>;

    using unique_bound_desc = unique_any_handle_null_only<decltype(&::DeleteBoundaryDescriptor), ::DeleteBoundaryDescriptor>;
}

What is the meaning of the last two lines?

I tried reading about "using", "decltype" and templates but I couldn't understand it in this context.

The full program can be found in: https://github.com/zodiacon/Win10SysProgBookSamples/tree/master/Chapter02/PrivateSharing2

vendredi 14 octobre 2022

ACE C++ Library class ACE_TASK doesn't have any activate function?

I have seen how to launch threads in my project, where we are using ACE library . But I have a question when ACE_TASK doesn't have any activate function how can you call it in class derived from MyClass class . The activate function is in ACE_TASK_BASE class which is derived from ACE_TASK . But MyClass class and ACE_TASK_BASE doesn't have any direct relation ?

class MyClass: public ACE_Task< ACE_MT_SYNCH >   {
    public:
    //derived from ACE_Task
    virtual int open( void *arg = NULL );
    //derived from ACE_Task
    virtual int svc();
};

//then we are calling

this->activate();    //  ?????

in open(); //running our job in

int svc() {
    while( _running )
       ....
}

Type Alias variable outside the template class in C++11 [duplicate]

namespace X
{
template <typename T>
clase A
{
public:
   using value = T;
   using pointer = T*;

   pointer member_fun();
private:
   value x{};

};
}

How to access the alias varaibles outside this template class in C++11? Is it like

template <typename T>
X::A<T>::value X::A<T>::member_fun(){

I am getting error here

Value of a variable is not updating inside the loop

In the following code, I am trying to count frequency of each non zero number

a[i] is actual array of index i, it is used to create array and store values. d[i] is used to create dupicate array with same values as a[i]. My intention of the code is to update freq after testing each case using nested loop but value of freq is not updating. freq value remains to be either 0 or 1. I tried to debug but still ending up with the same bug.

Some one please debug the code and fix it. Open for suggestions.

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

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int testcase,size;
    cin>>testcase;
    while(testcase--){
        cin>>size;
        int freq=0,total=0;
        int a[size];int d[size];
        for(int i=0;i<ns;i++){//to create array and duplicate arrray
            cin>>a[i];
            d[i]=a[i];
        }
        for(int i=0;i<ns;i++){
            if(d[i]==0 )continue;
            for(int j=0;j<ns;j++){ //duplicate array comparison
                cout<<"This is frequency"<<freq<<"This is total"<<total<<endl;

/*I used the above statement 
to check the behaviour of frequency value. Please ignore the above statement it if you want to.*/

                if(d[i]==d[j]){
                    freq=freq+1;
                    total=freq;
                    d[j]=0;
                }

            }
            d[i]=0;
            //cout<<"This is frequency"<<freq<<endl;
            freq=0;

//freq=0 is used to make value of the index position 0 if the number is checked once.


             cout<<"check frequency"<<freq<<endl;
        }


}
}

Keying an (unordered_)map using a multimap iterator

I'm building a software where one class is responsible to log info sources and commands (both are grouped as requests), where all requests are inserted inside a multimap, wherein the multimap is keyed by the request name, and each element points to request structure that holds management information and callback function pointer, insighted from this software.

The callbacks are executed to issue a command, or to get an info, and everything is ok until here.

To enable subscription-based information delivery, I've introduced a new map keyed by the request iterator, so where calling subscribe("infoID") the software looks for the exact match request and return its iterator.

Because these iterators are unique per request, I've found it useful to key the subscriptions map using it. Where the key points to info subscriber's callback-functions.

The error is:

error: no match for 'operator<' (operand types are 'const std::__detail::_Node_iterator<std::pair<const std::__cxx11::basic_string, request>, false, true>' and 'const std::__detail::_Node_iterator<std::pair<const std::__cxx11::basic_string, request>, false, true>') { return __x < __y; }

Followed by 15 compiling notes 'template argument deduction/substitution failed':

'const std::__detail::_Node_iterator<std::pair<const std::__cxx11::basic_string, request>, false, true>' is not derived from 'const std::pair<_T1, _T2>' { return __x < __y; } each one with a unique source: const std::pair<_T1, _T2>, const std::reverse_iterator<_Iterator> (stl_function.h), const std::reverse_iterator<_Iterator> (stl_iterator.h), ... etc.

Full error here.

Code:

#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
#include <functional>
#include <map>

using namespace std;

struct request
{
    string f1;
};

using   SYS_REQMAP          =unordered_multimap<string, request, hash<string>>;
using   SYS_REQMAP_I        =SYS_REQMAP::iterator;

using SYS_INFOSUB_CBF   = function<void(string, string)>;
using SYS_INFOSUB_CBFS  = vector<SYS_INFOSUB_CBF>;

using SYS_REQINF_SUBS   = map<SYS_REQMAP_I, SYS_INFOSUB_CBFS>;

void cbf(const string& a, const string& b){}
int main()
{
    SYS_REQINF_SUBS infoSubr;
    SYS_REQMAP vm,
                {"cmd2", {"bar"}}};

    for (SYS_REQMAP_I it = vm.begin(); it != vm.end(); it++)
    {
        printf("%lu\n", it);
        infoSubr[it].push_back(cbf);    // Compile error
    }
}

void compilesOK()
{
    using SYS_REQINF_SUBS_1 = std::map<int, SYS_INFOSUB_CBFS>;
    SYS_REQINF_SUBS_1 subs1;
    subs1[1].push_back(cbf);    // Compiles OK
}

And here's OnlineGDB link to compile and observe output.

Initializing an array of objects created on the heap

Given the non trivial data structure:

claas MyClass
{
public:
  MyClass():x(0), p(nullptr)
  {}

private:
  int x;
  int* p;
};

Is there any guarantee provided by the c++ specification that the default constructor will be called for each instance of MyClass in the array pointed by the ptr?

    int main()
    {
      MyClass* ptr = new MyClass[5];
    }

mercredi 12 octobre 2022

Creating

Is there a way in C++11, to create a container with map of interfaces as key and implementation classes as value of that key. What I wan't to do, is to be able to bind interfaces with certain implementations, then instantiate quickly class assigned to that interface. I'll explain using code:

Locator locator;

// binding ILogisticsCarrierPairingModel with DummyModel:
locator.bind<ILogisticsCarrierPairingModel, DummyModel>();

// instantiating DummyModel, by calling function with interface name:
ILogisticsCarrierPairingModel* model2 = locator.get<ILogisticsCarrierPairingModel>();

// binding ILogisticsCarrierPairingModel with LogisticsCarrierPairingModel:
locator.bind<ILogisticsCarrierPairingModel, LogisticsCarrierPairingModel>();

// now instantiating LogisticsCarrierPairingModel, by calling function with interface name:
model2 = locator.get<ILogisticsCarrierPairingModel>();

Thanks in advance.

conflicting declaration of C function With #ifdef __cplusplus

I failed to define overloading functions with error message of error: conflicting declaration of C function if enclosing by #ifdef __cplusplus blocks.

Below is a simple code for an easy view. This piece of code worked fine without #ifdef __cplusplus blocks.

However, my project code does need #ifdef __cplusplus as it involves combination of C and C++ codes.

Command lines after #ifdef __cplusplus block should be C++, why did it fail to define the overloading function? How to fix this problem with presence of #ifdef __cplusplus blocks?

#include <iostream>
using namespace std;

#ifdef __cplusplus
extern "C"
{
#endif

int add(int x)
{
    return x;
}

int add(int x, int y)
{
    return x + y;
}

int main() {
//  cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    int X = add(2);
    int Z = add(8,2);

    cout <<X<<" "<<Z<<endl;
    return 0;
}

#ifdef __cplusplus
}
#endif