lundi 30 novembre 2020

Question about template's value_type usage in Stroustrup's book example

In Stroustrup's "A Tour of C++" there is a code snippet

template<typename C>
using Value_type = typename C::value_type;  // the type of C’s elements

template<typename Container>
void algo(Container& c)
{
    /* (1) */ 
    Vector<Value_type<Container>> vec;  // keep results here
    // ...
}

Why we need this using, how it differs from writing in (1) just

Vector<Container::value_type> vec;

2d vectors c++ swapping rows/columns

Just out curiosity, is it possible to swap rows/columns of a 2d vector with the STL swap_ranges function, like:

void swooop(std::vector<std::vector<int>>& ar2d) {
    swap_ranges(ar2d.begin()->begin(), ar2d.begin()->end(), (ar2d.end()-1)->begin());
}

having coordinate issues with my drawings

Recently I had problems with drawing a grid and making a pop-up menu for it to turn the grid on and off, I have now solved this problem with a bit of help but now whenever I want to draw something (I am now trying to draw a boundary like this enter image description here

when I try to add the boundary with my grid that I have created I have been having problems, probably with my coordinates but I don't know how to solve it, this is how it is looking. enter image description here

#include "include\freeglut.h"   // OpenGL toolkit - in the local shared folder
#include <iostream>

//set up some constants
#define carX_CENTRE -150.0      /* centre point of the car */
#define carY_CENTRE -150.0
#define X_CENTRE 0.0      /* centre point of square */
#define Y_CENTRE 0.0

#define LENGTH   20.0 

//GLfloat red = 1.0, green = 1.0, blue = 1.0;

GLboolean grid = false;

int w = 1;
int h = 1;

 /* reshape callback function
 executed when window is moved or resized */
 void reshape(int width, int height)
{
glViewport(0, 0, width, height);
/* uses orthographic (parallel) projection
use xmin = -1, xmax = 1
ymin = -1, ymax = 1
znear = -1, zfar = 1 - not relevant here (2D) */
w = width;
h = height;
glMatrixMode(GL_PROJECTION);
glOrtho(0.0, (float)w, (float)h, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}

void drawBoundary(float length, float x, float y)
{

glBegin(GL_LINE_LOOP);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(X_CENTRE - length - 20, Y_CENTRE - length);   //these 4 points draw the game boundary
glVertex2f(X_CENTRE - length - 20, Y_CENTRE + length);   //these 4 points draw the game boundary
glVertex2f(X_CENTRE + length + 20, Y_CENTRE + length);   //these 4 points draw the game boundary
glVertex2f(X_CENTRE + length + 20, Y_CENTRE - length);   //these 4 points draw the game boundary
glEnd();

glFlush();     /* execute drawing commands in buffer */
}

/* display callback function
called whenever contents of window need to be re-displayed */
//this is the all important drawing method - all drawing code goes in here
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);   /* clear window */
//glColor3f(red, green, blue);        /* white drawing objects */
glColor3f(0.8, 0.8, 0.8);

GLint i;

glEnable(GL_LINE_STIPPLE); //Activates the line-style feature

glLineStipple(1, 0xAAAA);  // Plots a dashed polyline

if (grid) {
glBegin(GL_LINES);
for (i = 2; i <= 9; i++)
{
    glVertex3f(i * 0.1 * w, 0.0, 0.0);
    glVertex3f(i * 0.1 * w, 0.9 * h, 0.0);
}

for (i = 1; i <= 9; i++)
{
    glVertex3f(0.1 * w, i * 0.1 * h, 0.0);
    glVertex3f(w, i * 0.1 * h, 0.0);
}
glEnd();
glDisable(GL_LINE_STIPPLE);
}

drawBoundary(170, 0, 0);

glFlush();     /* execute drawing commands in buffer */
}

void myGridmenu(GLint id)
{
if (id == 1)
{
    grid = 1.0;
}
else
{
    grid = 0.0;
}
glutPostRedisplay();
}

/* graphics initialisation */
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);   /* window will be cleared to black */
}

//rename this to main(...) and change example 2 to run this main function
int main(int argc, char** argv)
{
/* window management code ... */
/* initialises GLUT and processes any command line arguments */
glutInit(&argc, argv);
/* use single-buffered window and RGBA colour model */
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
/* window width = 400 pixels, height = 400 pixels */
glutInitWindowSize(500, 500);
/* window upper left corner at (100, 100) */
glutInitWindowPosition(100, 100);
/* creates an OpenGL window with command argument in its title bar */
glutCreateWindow("Coursework 1");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);

//Create a grid that the user can turn on and off
glutCreateMenu(myGridmenu);

glutAddMenuEntry("Grid on", 1);
glutAddMenuEntry("Grid off", 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);

glutMainLoop();
return 0;
}

What is the different between C++11 non-type template parameter and C++17 non-type template parameters?

Consider this code:

using func = int (*)(int, int);

template<func F>
void  do_something(int first, int second) {}

int   something(int first, int second) {}

void  f()
{
  constexpr auto  function = something;
  do_something<function>(10, 20);
}

Which is compiled and run with C++17 standard compatible compiler, but it's fail with C++11 standard:

 error: no matching function for call to ‘do_something<function>(int, int)’
   17 |   do_something<function>(10, 20);

What it's the difference between C++11 non-type template parameters and C++17 non-type template parameters ? in §14.1.4 [temp.param][n3690]:

A non-type template-parameter shall have one of the following (optionally cv-qualified) types: — integral or enumeration type,
— pointer to object or pointer to function,
— lvalue reference to object or lvalue reference to function,
— pointer to member,
— std::nullptr_t.

And in §17.1.4 [temp.param][n4713]:

A non-type template-parameter shall have one of the following (optionally cv-qualified) types: (4.1) — integral or enumeration type,
(4.2) — pointer to object or pointer to function,
(4.3) — lvalue reference to object or lvalue reference to function,
(4.4) — pointer to member,
(4.5) — std::nullptr_t, or
(4.6) — a type that contains a placeholder type (10.1.7.4).

The only different is:

< — a type that contains a placeholder type (10.1.7.4).

Which i don't think it's related to my question because a placeholder type is something like auto, and i sent a value to template not a placeholder type or a type.

Advantage of using Factory method in C++

I was asked to create a Factory method and was asked to invoke the method "createEMRProcess" using factory method. Could anyone Please suggest any improvement or suggestions?

Below is the Factory Class and Factory method:

EMRFactory.h:

class CEMRFactory
{
public:
 std::shared_ptr<CTestImpl> createEMR(IMedOrder* f_hMedOrder, int f_nProductID, int f_nMedId);
};

EMRFactory.cpp:

#include "EMRFactory.h"

std::shared_ptr<CTestImpl> CEMRFactory::createEMR(IMedOrder* f_hMedOrder, int f_nProductID, int f_nMedId)
{
    return CTestImpl::getInstance(f_hMedOrder, f_nProductID, f_nMedId);
}

From the factory method, we are invoking the getInstance. And getInstance method is implemented in CTestImpl like as shown below:

TestImpl.h:

static shared_ptr<CTestImpl>               ms_hActiveInstance;

TestImpl.cpp

shared_ptr<CTestImpl> CTestImpl :: ms_hActiveInstance = NULL;

shared_ptr<CTestImpl> CTestImpl::getInstance(IMedOrder* f_hMedOrder, int f_nProductID, int f_nMedId)
{
    if (NULL == ms_hActiveInstance)
    {
        ms_hActiveInstance = shared_ptr<CTestImpl> (new CTestImpl(f_hMedOrder, f_nProductID, f_nMedId));
    }
    return ms_hActiveInstance;
}

I am using the Factory method in the below class like as shown below. And then invoking the method:

MainImpl.h

std::shared_ptr<CTestImpl> m_pTestImpl;
shared_ptr<CEMRFactory>   m_pEMRCollection;

MainImpl.cpp

void processApp()
{
 m_pTestImpl = m_pEMRCollection->createEMR(this, 1, 1);
 m_pTestImpl->createEMRProcess("EMR", Id, true, false);
}

Convert utf16 unsigned short to utf8 unsigned char

I have the following:

unsigned short *name = new unsigned short[name_size];
memcpy_s(name, name_size*2, &byteArray[offset], name_size*2);

The source is utf16-LE and I would like to work with UTF8 in an array of chars. Is there a library for the conversion? Or can someone guide me to find the algorithm to do it myself?

For now it is enough for me to delete the second byte, which is always 00 since most of the information is plain text, but I know that is not the way to do it.

Program that holds evidents of students in a group.Smply chained lists

Program that holds evidents of students in a group. For every student u need: first name, last name and grade.

  • to add a new student in the group,
  • to delete a student from the group,
  • to identifiy student "X" and to be deleted,
  • to identifiy the students for scholarship grade>8.00,
  • ordering the students by grade, modifing the bonds;

I have no idea how to start this, my professor didn't do any of this with my class.

How do I fix the Werror=parantheses (suggest parantheses around assignment) error?

I have a line of code which does both assignment and condition. I could split it into two lines but I'm just curious about the error message thrown.

  if ( parameters->__size = m_Elements.size() ) 

Got this error: suggest parentheses around assignment used as truth value [-Werror=parentheses]

I tried:

   if ( (parameters->__size) = (m_Elements.size()) )

The error doesn't go away. But I feel I have done what I was prompted to do and added parentheses around the assignment. Why doesn't the error go away? What am I missing?

How to use binary operator oveloading correctly [duplicate]

How should binary operator be overloaded,
CMyClass operator-(const CMyClass& oMyClass) const or
CMyClass operator-(const CMyClass& oMyClass)
What is the difference between both, Can the first call replace the second one completely.
I have found that using the second one only I wont be able to add const MyClass as LHS.

#include <iostream>
class CMyClass
{
    int m_y{ 0 };
    int m_x{ 0 };

public:
    CMyClass()
    {
    }

    CMyClass(int x, int y) :
        m_x{ x }, m_y{ y }
    {}

    CMyClass operator-(const CMyClass& oMyClass) const
    {
        CMyClass oReturn;
        oReturn.m_x = m_x - oMyClass.m_x;
        oReturn.m_y = m_y - oMyClass.m_y;
        return oReturn;
    }

    CMyClass operator-(const CMyClass& oMyClass)
    {
        CMyClass oReturn;
        oReturn.m_x = m_x - oMyClass.m_x;
        oReturn.m_y = m_y - oMyClass.m_y;
        return oReturn;
    }
};

int main()
{
    const CMyClass p1(10, 10);
    const CMyClass p2(5, 5);

    CMyClass p3 = p1 - p2;
    // ...
}

ERROR: : OperationAborted: Unable to parse ExceptionName: OperationAborted Message:

I am getting this error. I am trying to upload mp4 files to aws s3 using aws-sdk-cpp.

I am uploading video files and applying lifecycleRule on those objects but i am getting error. i am using one key/prefix to write few files to aws s3 and applying lifecyclerule.

ERROR: : OperationAborted: Unable to parse ExceptionName: OperationAborted Message: A conflicting conditional operation is currently in progress against this resource. Please try again. with address ...

Template Class with Multiple Variadic Parameter Packets

I want to ask how a template class could have Variadic Parameter Packets.

I'm writing a template creator for building template objects. and the object must accept 2 variadic parameter packets.

If I have specialize the object, this object would be created, otherwise, an empty object be returned from the creator.

Here is the demo code and the use case.

#include <iostream>
#include <memory>

// defualt creator which returns empty object
template<
    typename... Args1, template<typename...> typename T,
    typename... Args2, template<typename...> typename U,
    template<template<typename...> typename, 
             template<typename...> typename> typename Object, // the object must accpet 2 variadic parameter packets
    bool = Object<T<Args1...>, U<Args2...>>::value>           // the boolean is for specilization
class MyCreator
{
public:
    using ObjectType = Object<T<Args1...>, U<Args2...>>;

    template<typename... Args>
    static std::unique_ptr<ObjectType> New(Args&&...)
    {
        return std::unique_ptr<ObjectType>(); // returns a empty object
    }
};

// specalized creator which returns a real one
template<
    typename... Args1, template<typename...> typename T,
    typename... Args2, template<typename...> typename U,
    template<template<typename...> typename, 
             template<typename...> typename> typename Object>
class MyCreator<Args1..., T, Args2..., U, Object, true> // specalize the last boolean for true
{
public:
    using ObjectType = Solver<T<Args1...>, U<Args2...>>;

    template<typename... Args>
    static std::unique_ptr<ObjectType> New(Args&&...args)
    {
        return std::make_unique<ObjectType>(std::forward<Args>args...); // returns a real object
    }
};

// the interface for object
template<
    typename... Args1, template<typename...> typename T,
    typename... Args2, template<typename...> typename U
class ObjectImpl : public std::false_type
{
public:
    virtual void Print() = 0; // only Print(), just for demo
};

// the default object which should not be instantiate
template<
    typename... Args1, template<typename...> typename T,
    typename... Args2, template<typename...> typename U
class Object : public ObjectImpl<Args1..., T, Args2..., U>, public std::false_type
{
};

// the specilized object which could be instantiated, just for demo
template<
    char,  int,    std::tuple,
    float, double, std::tuple,
class Object : public ObjectImpl<Args1..., T, Args2..., U>, public std::true_type
{
public:
    void Print() override
    { 
        std::cout<< std::tuple_size<std::tuple<char, int>>::value << std::endl;
        std::cout<< std::tuple_size<std::tuple<float, double>>::value << std::endl;
    };
};

// use case
int main()
{
    // create obj using creator
    auto obj = MyCreator<char,  int,    std::tuple
                         float, double, std::tuple,
                         Object>().New();

    // call the obj if enable
    if(obj)
    {
        obj->Print();   
    }

    return 0;
}

I have found an answer for tempalate fuction How can I have multiple parameter packs in a variadic template? but could not fix the issue for template class with the Variadic Parameter Packets?

How to create and invoke the Factory method from a different class in C++

In "Class A", I have a function named "IsTestEMRCreated".

From "Class B", I need to invoke the method "IsTestEMRCreated"

I was asked to create a Factory method in "Class A" and using that factory method or class, invoke "IsTestEMRCreated" from "class B".

I never used Factory method. Could someone please help me on this.

dimanche 29 novembre 2020

Why there is still a inline specifier when member fuctions define inside class?

The C++ ISO standard says: A function defined within a class definition is an inline function.

But look at the code as follows: leveldb-skiplist

class template <typename Key, class Comparator>
class SkipList{
 public:
  /*
   ...
  */
 private:
  inline int GetMaxHeight() const {
    return max_height_.load(std::memory_order_relaxed);
  }
};

there is still an explicit inline specifier when GetMaxHeight is defined inside class.

So, I want to know why we still need an explicit inline when a function defined within a class?

Why do I need static_cast and std::remove_reference in std::move if I pass an rvalue?

I'm trying to understand more move semantic. Now this is a possible implementation of std::move:

template <typename T>
typename std::remove_reference<T>::type&& move_(T&& obj)
{
    return static_cast<typename std::remove_reference<T>::type&&>(obj);
}
  • But I've edited it a bit to understand its workings:

      template <typename T>
      typename std::remove_reference<T>::type&& move_(T&& obj)
      {
          if(std::is_lvalue_reference<decltype(obj)>::value)
              return static_cast<typename std::remove_reference<T>::type&&>(obj); 
          return obj; // dones't work?
          // return (string&&)obj; // ok works
      }
    
      auto s = move_(std::string("Hi there!")); // passing an rvalue cause instantiating: `string&&(string&&){}`. 
    

But why I can't directly return obj which is of revalue-reference type after instantiation?

Unable to compile with Clang using cc command. What am I missing?

I am using the new M1 MacBook Pro and I am setting up my development environment. I have installed gdb using homebrew, though I am unable to compile using cc. What software am I missing?

Note: I do not want to use gcc/g++, I want to use Clang specifically. See below for an example of the errors I receive with compiling with Clang.

% cc test.cpp                              
Undefined symbols for architecture arm64:
  "std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from:
      std::__1::ctype<char> const& std::__1::use_facet<std::__1::ctype<char> >(std::__1::locale const&) in test-31f101.o
  "std::__1::ios_base::getloc() const", referenced from:
      std::__1::basic_ios<char, std::__1::char_traits<char> >::widen(char) const in test-31f101.o
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(unsigned long, char)", referenced from:
...
...
...
...
A lot more errors...

Can you import export functions in c++?

I am working on a c++ program, however, the size of the program is huge. I was wondering if there is any way in which I can reduce the program size. For example, if js, one can import and export function, so can we do the same in c++ as well? If there is a way, please let me know.

What is wrong with my recursion? Max Subarray Problem

I'm solving the max Subarray problem with recursion but I'm getting a runtime error. I cannot figure out what the problem is. Please help me understand if you get it. Please help me with the same:

    class Solution {
public:
    int cross(vector<int>a, int l, int m, int h)
    {
        int ls=INT_MIN;
        int sum=0; 
        for(int i=m; i>0; i--)
        {
            sum=sum+a[i];
            if(ls<=sum)
            {
                ls=sum;
            }
        }
        sum=0;
        int rs=INT_MIN; 
        for(int i=m+1; i<h; i++)
        {
            sum=sum+a[i];
            if(rs<=sum)
            {
                rs=sum;
            }
        }
        return (ls+rs);
    }
    int mainfunc(vector<int>a, int l, int h)
    {
        if (l==h) {return a[0];}
        
        int m=l+(h-1)/2;

        int lsum=mainfunc(a, l, m);
        int rsum=mainfunc(a, m+1, h);
        int csum=cross(a, l, m, h);
        
        if (lsum>=rsum && lsum>=csum){return lsum;}
        else if (rsum>lsum && rsum>csum){return rsum;}
        else return csum;
    }
    int maxSubArray(vector<int>& n) {
        int sum=mainfunc(n, 0,  n.size());
        return sum;
    }
};

What are "names which are not lvalues"?

There's an entry in the errata of Effective Modern C++ which says that

not all names are lvalues

What are these names? Specifically,

  1. is Scott just referring to the nullptr and this named prvalues?
  2. Are there any others?
  3. In case the answer to 1 is yes, then what makes nullptr special with respect to true and false? They are all values of some type (true/false of type bool, nullptr of type std::nullptr_t). After all true stays to bool just like 1 stays to int, and 1 is not a "name which is not an lvalue", is it? At this point I'd ask why is true not a name then?

C++ | Connecting source files issue

Edit: Ok, so whole code is here: https://www.github.com/LatekVon/RavenOs I have couple seperate source files i want to link, but it just doesn't work. In single file i have couple functions, and some are recognized by compiler and some are not. Just so you know, this program worked when being a singular mess, but now it doesnt. Compiler even throws error saying, that stringSplit is not recognized, even thought countString is. Every single file has same #include files. #include "header.h" is in every file, and in header itself, every function is listed. Here is header, the shortest file:

#ifndef KERNEL_H
#define KERNEL_H

//is this really needed?
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector> 
#include <deque>
#include <cstdlib>
#include <chrono>

using namespace std; //added this after edit!

#define VGA_ADDRESS 0xB8000
#define WHITE_COLOR 15
typedef unsigned short UINT16;//16bit value

//Pub values
string user_name;

//VGA
static UINT16 VGA_DefaultEntry(unsigned char ch_to_print);
UINT16 *TERMINAL_BUFFER;

//UTILS
int countString(string str);
string splitString(string str, int index);
void log(string str);

//PARSER
bool programParser(string program, string wholeString);

#endif

And im sure, i can fix problem for myself after putting here just one of the files, as error occurs in every file, and files like parser.cpp are just gonna add mess to this problem. Only info about parser.cpp you probably need to know, is that it calls utils.cpp and both of these files, as i said earlier, have #include "header.h" file. Here is 'utils.cpp':

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector> 
#include <deque>
#include <cstdlib>
#include <chrono>

#include "kernel.h"

using namespace std;

//a 16bit rendering of characters
static UINT16 VGA_DefaultEntry(unsigned char ch_to_print){
    //left shift converts color to character value pixel encoding
    return (UINT16)ch_to_print | (UINT16)WHITE_COLOR << 8;
}

//will split strings and return word from zero

int countString(string str){
    cout << "entered countString() module" << endl;
    stringstream countString_stream(str);
    int countString_finalCount = 0;
    string counterString = "";

    while(countString_stream >> counterString){ 
        countString_finalCount++;
    }

    return countString_finalCount;
}
string splitString(string str, int index){ /*index from 0*/
    cout << "entered splitString() module" << endl;
    if(countString(str) <=  1){//if 0 or 1 then return input//
        return str;
    }
    stringstream splitString_stream(str);
    string spliced = "";

    for(int i = 0; i <= index && splitString_stream.rdbuf()->in_avail() != 0; i++){
        splitString_stream >> spliced;
        cout << "debug: splitString: spliced = " << spliced << endl;
    }
    splitString_stream.clear();
    cout << "debug: splitString: output = " << spliced << endl;
    return spliced;
}
void log(string str){
    static string entryID = "["+ chrono::steady_clock::now +"]"+ user_name + ": ";
    ofstream logFileO;
    ifstream logFileI;
    if(logFileO.is_open() == false){
        if(logFileI.is_open() == false){
            logFileI.open("logs.data");
        }
        logFileO.open("logs.data");
        string tempString;
        deque<string> tempDeque;
        while(getline(logFileI,tempString){
            tempDeque.push_back(tempString);
        }
        while(deque.empty() == false){
            logFileO << tempDeque.front;
            tempDeque.pop_front;
        }
    }
    logFileO << entryID << str;
}

As last note: As you can see, i have all #include files also in header, i have no idea if its right thing to do, but it didnt work either way. Also, compiler command i used is: g++ -o kernel utils.cpp main.cpp parser.cpp I didnt inlclude header, as it threw even more errors regarding functions not being initialized/declared (i mistake these two). After edit, decided to also put this code here:

//counting args
    int argAmount = countString(wholeString) - 1;//this includes input but not program name
    int argAmountActual = 0;//only -x arguments
    int argAmountInputs = argAmount;
        
    //cant just check last arg for input as it could be in centre
        
    for(int i = 0; i <= argAmount; i++){
        string tempString = "";
        tempString = splitString(wholeString, i);
        cout << "debug: programParser: tempString = " << tempString << endl;
        if(tempString.size() != 0){
            if(tempString.at(0) == '-'){
                argAmountActual++;
            }
        }
    }

Its very important, as countString can be called and recognized, but splitString cannot. I know that this code is flawed, but im more intrested why does countString work, and splitString doesn't. Cheers

samedi 28 novembre 2020

How do I Avoid Using the Copy Constructor in A Setter

Apologies if this is a basic question, I am new to C++. Let us say I have 2 classes, A and B, defined as below:

class A {
    public:
        A(int i) { a = i; };
        A(A&) = default;
        int a;
};
class B {
public:
    B(A& a) : this_a(a) {};
    B(B&) = default;
    A& this_a;
    void set_a(A& a) {
        this_a = a;
    };
};

and let us say my main method is:

int main()
{
    A a1(5);
    A temp(5);
    B e(temp);
    cout << a1.a << endl;
    e.set_a(a1);
    e.this_a.a = 0;
    cout << a1.a << endl;
    cout << e.this_a.a << endl;

    return 0;
}

The output for this code is:

5
5
0

As far as I can tell, this is the output because in my setter, the copy constructor is being used for the A reference being stored in the B object. This is why:

int main()
{
    A a1(5);
    B e(a1);
    cout << a1.a << endl;
    e.this_a.a = 0;
    cout << a1.a << endl;

    return 0;
}

Outputs:

5
0

Is there any way for me to be able to write the setter in such a way that I can still access the member by reference?

ODBC query execution failure

ALL,

I am trying to build an application in C++ that connects to Sybase SQL Anywhere with the native Sybase ODBC driver. The application is trying to execute query with 2 parameters.

When trying to execute the query with SQLExecute() I am getting an error as in the subject.

This query does execute correctly inside the same binary when the connection is done to any other DBMS (MS SQL, Postgre, mySQL). It also works correctly if I insert the query inside the ISQL utility of SQL Anywhere (but presumably it does not use ODBC, but rather ct-lib).

Looking at some of the answers here on SO, people suggest that sme parameter value might be NULL. I checked under the MSVC debugger and the variables that contain those values are definitely not NULL (both of them).

The other suggestion was that there was a problem with the query itself (copy/paste). Since the query works with the ISQL, this is not the case either.

So, any other possibilities why the query fails?

TIA!!

Compile error using variadic templates multiple times as arguments with VS 2019.27

Basic information

  • source code is below this text.
  • compiles with nearly every compiler not older than 5 years (gcc 6, ...)
  • compiles NOT with MS VC up to MS VC 2019 16.27
  • looks like there's a problem using a variadic template as a argument prototype of a function pointer more than once.

Questions:

  • code wrong or compiler wrong??
  • any possibility to write this more elegant and more standard conform so MS VS compiles it?
  • output at the end of the code is from compiler explorer.
#include <iostream>

// https://godbolt.org/
// https://www.onlinegdb.com/online_c++_compiler
// http://cpp.sh/

using std::ostream;
using uint = unsigned int;

template <typename... Ts> 
uint  Start (const char* String,
             void      (*fn1) (Ts...),           // Works fine with every compiler 
             Ts&&...     args)
{
    std::cout << String << ' ' << __FUNCTION__ << '\n';
    if (fn1) fn1 (args...);
    return 1;
}
template <typename... Ts> 
uint  Start (const char* String,
             void      (*fn1) (Ts...),
             void      (*fn2) (Ts...),  // Microsoft-Compiler makes trouble here using Ts a second time... ***
             Ts&&...     args)
{
    std::cout << String << ' ' << __FUNCTION__ << '\n';
    if (fn1) fn1 (args...);
    if (fn2) fn2 (args...);
    return 2;
}
template <typename... Ts> 
uint  Start (const char* String,
             void      (*fn1) (Ts...),
             void      (*fn2) (Ts...),
             void      (*fn3) (Ts...),
             Ts&&...     args)
{
    std::cout << String << ' ' << __FUNCTION__ << '\n';
    if (fn1) fn1 (args...);
    if (fn2) fn2 (args...);
    if (fn3) fn3 (args...);
    return 3;
}

void Fn1 (double x)        { std::cout << __FUNCTION__ << ' ' << 1*x << '\n'; }
void Fn2 (double x)        { std::cout << __FUNCTION__ << ' ' << 2*x << '\n'; }
void Fn3 (double x)        { std::cout << __FUNCTION__ << ' ' << 3*x << '\n'; }

void Gn1 (double x, int y) { std::cout << __FUNCTION__ << ' ' << 1*x << ' ' << 1*y << '\n'; }
void Gn2 (double x, int y) { std::cout << __FUNCTION__ << ' ' << 2*x << ' ' << 2*y << '\n'; }
void Gn3 (double x, int y) { std::cout << __FUNCTION__ << ' ' << 3*x << ' ' << 3*y << '\n'; }

int
main()
{
    std::cout << __FUNCTION__ << '\n';
    
    std::cout << Start <double>      ("Test 1" , Fn1, 12.34) << " returned\n";

    std::cout << Start <double>      ("Test 2" , Fn1, Fn2, 12.34) << " returned\n";
    
    std::cout << Start <double>      ("Test 3a", Fn1, Fn2, Fn3, 12.34) << " returned\n"; 

    std::cout << Start <double, int> ("Test 3b", Gn1, Gn2, Gn3, 12.34, 42) << " returned\n"; 
    
    std::cout << Start <double, int> ("Test 3c", 
                                      *[] (double x, int y) -> void { std::cout << __FUNCTION__ << ' ' << 1*x << ' ' << 1*y << '\n'; }, 
                                      *[] (double x, int y) -> void { std::cout << __FUNCTION__ << ' ' << 2*x << ' ' << 2*y << '\n'; }, 
                                      *[] (double x, int y) -> void { std::cout << __FUNCTION__ << ' ' << 3*x << ' ' << 3*y << '\n'; }, 
                                      3.14159, 42) << " returned\n";
    return 0;
}

/* 

x64 msvc v19.27

exxample.cpp
<source>(59): error C2660: 'Start': function does not take 4 arguments
<source>(11): note: see declaration of 'Start'
<source>(61): error C2672: 'Start': no matching overloaded function found
<source>(61): error C2782: 'uint Start(const char *,void (__cdecl *)(Ts...),Ts &&...)': template parameter 'Ts' is ambiguous
<source>(11): note: see declaration of 'Start'
<source>(61): note: could be 'double'
<source>(61): note: or       'void(__cdecl &)(double), double'
<source>(63): error C2660: 'Start': function does not take 6 arguments
<source>(11): note: see declaration of 'Start'
<source>(66): error C2593: 'operator *' is ambiguous
<source>(66): note: could be 'built-in C++ operator*(main::<lambda_00de9a703c525e1d30b87861a11e038f>::<lambda_typedef_cdecl>)'
<source>(66): note: or       'built-in C++ operator*(main::<lambda_00de9a703c525e1d30b87861a11e038f>::<lambda_typedef_vectorcall>)'
<source>(66): note: while trying to match the argument list '(main::<lambda_00de9a703c525e1d30b87861a11e038f>)'
<source>(66): error C2100: illegal indirection
<source>(67): error C2593: 'operator *' is ambiguous
<source>(67): note: could be 'built-in C++ operator*(main::<lambda_63e8d9ca3695b55d9d6dc9dda05048f3>::<lambda_typedef_cdecl>)'
<source>(67): note: or       'built-in C++ operator*(main::<lambda_63e8d9ca3695b55d9d6dc9dda05048f3>::<lambda_typedef_vectorcall>)'
<source>(67): note: while trying to match the argument list '(main::<lambda_63e8d9ca3695b55d9d6dc9dda05048f3>)'
<source>(67): error C2100: illegal indirection
<source>(68): error C2593: 'operator *' is ambiguous
<source>(68): note: could be 'built-in C++ operator*(main::<lambda_9769e2f1b0b076d22151082820474129>::<lambda_typedef_cdecl>)'
<source>(68): note: or       'built-in C++ operator*(main::<lambda_9769e2f1b0b076d22151082820474129>::<lambda_typedef_vectorcall>)'
<source>(68): note: while trying to match the argument list '(main::<lambda_9769e2f1b0b076d22151082820474129>)'
<source>(68): error C2100: illegal indirection
Compiler returned: 2

*/

C++ Tuple from template first classes

I need to take first argument of unlimited template and pass it as tuple template

template<template<class A, class B> class... InputStreamProcessingType>
class integrated_processing
{
     // I want something like this
     void process(std::tuple<A...> input)
}

Can't find a way to delete elements of a class object vector [duplicate]

I am using a vector of class types for my school project. The vector is called knightVec and I can use some vector functions no prob, for example knightVec.size() or knightVec.push_back(...) but when I try to use knightVec.erase(1) (or any position) it throws this error:

no instance of overloaded function "std::__1::vector<_Tp, _Allocator>::erase [with _Tp=Knight, _Allocator=std::__1::allocator<Knight>]" matches the argument list -- argument types are: (int) -- object type is: std::__1::vector<Knight, std::__1::allocator<Knight>>C/C++(304)

I can use member functions of the class, like in knightVec[1].getHealth() and those don't give errors.

Template Aliases - question (tour of c++)

I was going through the template Aliases from Tour of C++. I couldn't understand the below code and how to use it?

template<typename T>
class Vector {
public:
   using value_type = T; 
}

Here he is using the value_type as type alias for typename 'T', Why can't we just use the typename T, since we can pass any type to template(i.e. class Vector). What is the need to have alias for template?

template<typename C>
using Value_type = typename C::value_type;

Here how is value_type in the scope of C, i.e. how can we reference value_type with type 'C', since it is inside class "vector"? does 'value_type' here mean its a Vector? and 'Value_type' mean int::Vector or string::Vector etc..?

template<typename Container>
void algo(Container &c)
{
  Vector<Value_type<Container>> vec;
}

How are these three pieces linked?

How to refer to private variables as arguments in auxiliary functions in a generic template

I am doing a project using generic templates in C++ in modular programming (we don't use OOP concepts)

We are having an issue understanding how to refer in an auxiliary function to a single variable in the template, which is a struct itself, without referring to the whole struct.

To put an example, because it sounds weird, we have:

template<typename T>
struct tree {
    friend void addElement<T> (tree<T>& c, const T& e);
    struct Node {
        T element; // template element
        Nodo* left;
        Nodo* right;
    };
 
    Node* root;
    int size;

}

template<typename T>
void friend void addElement<T> (tree<T>& c, const T& e);
    insert(c.root, e);
    c.size++;
}

// auxiliary function
template<typename T>
void insert(tree<T>root node, const T& e) { 
// how to refer to taking a Node* as an argument? we want 
// to modify the node structure of the tree in a recursive way, 
// so we will need to pass Node->left or Node->right as arguments
    // code 
}

We have tried multiple ways of doing this, none worked so far. How could this be done?

Thanks!

Programme is not executing even not having any comile error

    #include <iostream>
using namespace std;


void aUnionB(int A[], int B[], int a, int b)
{
    int n = a + b;
    int aUb[n]{0}; // n is max num of elements aUb can have

    // filling elements of a in aUb
    for (int i = 0; i < a; i++)
    {
        aUb[i] = A[i];
    }

    int z = sizeof(aUb) / sizeof(aUb[0]);
    int temp = z;
    // compare element from set B with aUb and if not fount add it in aUb
    for (int i = 0; i < z; i++)
    {
        for (int j = 0; j < b; j++)
        {
            if (aUb[i] == B[j])
            {
                continue;
            }
            else
            {
                aUb[temp] = B[j];
                temp++;
            }
        }
    }
    //print a union b
    for (int i : aUb)
    {
        cout << i << " ";
    }
}

int main()
{
    int TestCases = 1, NoOfElementsInA, NoOfElementsInB, element;

    while (TestCases--) //testing for just one test case
    {
        cin >> NoOfElementsInA >> NoOfElementsInB;
        int A[NoOfElementsInA], B[NoOfElementsInB];

        //assigning elements in array A
        for (int i = 0; i < NoOfElementsInA; i++)
        {
            cin >> element;
            A[i] = element;
        }
        //assigning elements in array B
        for (int i = 0; i < NoOfElementsInB; i++)
        {
            cin >> element;
            B[i] = element;
        }

        aUnionB(A, B, NoOfElementsInA, NoOfElementsInB);
    }
    return 0;
}

I am trying for past 1 hour what's the problem but unable to find why the program is not running despite not having any error or warning after execution , I'm not able to pass inputs.

This the numerical question:

The first line of input contains an integer T denoting the number of test cases. Then T test cases follow. Each test case consist of three lines. The first line of each test case contains two space separated integers N and M, where N is the size of array A and M is the size of array B. The second line of each test case contains N space separated integers denoting elements of array A. The third line of each test case contains M space separated integers denoting elements of array B.

vendredi 27 novembre 2020

Is the value of steady_clock::now from multiple threads consistent with memory order?

Within one thread, steady_clock::now() is guaranteed to return monotonically increasing values. How does this interact with memory ordering and reads observed by multiple threads?

atomic<int> arg{0};
steady_clock::time_point a, b, c, d;
int e;
thread t1([&](){
    a = steady_clock::now();
    arg.store(1, memory_order_release);
    b = steady_clock::now();
});
thread t2([&](){
    c = steady_clock::now();
    e = arg.load(memory_order_acquire);
    d = steady_clock::now();
});
t1.join();
t2.join()
assert(a <= b);
assert(c <= d);

Here's the important bit:

if (e) {
    assert(a <= d);
} else {
    assert(c <= b);
}

Can these assert ever fail? Or have I misunderstood something about acquire release memory order?

What follows is mostly an explanation and elaboration of my code example.

Thread t1 writes to the atomic arg. It also records the current time before and after the write in a and b respectively. steady_clock guarantees that a <= b.

Thread t2 reads from the atomic arg and saves the value read in e. It also records the current time before and after the read in c and d respectively. steady_clock guarantees that c <= d.

Both threads are then joined. At this point e could be 0 or 1.

If e is 0, then t2 read the value before t1 wrote it. Does this also imply that c = now() in t2 happened before b = now() in t1?

If e is 1 then t1 wrote the value before t2 read it. Does this also imply that a = now() in t1 happened before d = now() in t2?


Here are some existing questions that don't answer what I'm asking:

Is there any std::chrono thread safety guarantee even with multicore context?

I'm not asking whether now() is thread-safe. I know it is.

Is steady_clock monotonic across threads?

This one is much closer, but that example uses mutex. Can I make the same assumptions about memory orderings weaker than seq_cst?

Does `steady_clock::now()` have total order? [duplicate]

Within one thread, steady_clock::now() is guaranteed to return monotonically increasing values. How does this interact with memory ordering and reads observed by multiple threads?

atomic<int> arg{0};
steady_clock::time_point a, b, c, d;
int e;
thread t1([&](){
    a = steady_clock::now();
    arg.store(1, memory_order_release);
    b = steady_clock::now();
});
thread t2([&](){
    c = steady_clock::now();
    e = arg.load(memory_order_acquire);
    d = steady_clock::now();
});
t1.join();
t2.join()
assert(a <= b);
assert(c <= d);

Here's the important bit:

if (e) {
    assert(a <= d);
}

Can that assert ever fail? Or have I misunderstood something about acquire release memory order?

File readable but saved in binary mode

I wrote a very simple function that saves a file in binary mode with the support of qt. The file is saved correctly and the data inside is correct, however if I open the file with a text editor I can read strings that I shouldn't be reading.

void Game::saveRanking() const
{
    QFile file(".ranking.dat");
    file.open(QFile::WriteOnly);

    QJsonObject recordObject;

    QJsonArray rankingNameArray;
    for (int i = 0; i < 5; i++)
        rankingNameArray.push_back(QJsonValue::fromVariant(QVariant(highscoreName[i])));
    recordObject.insert("Ranking Name", rankingNameArray);

    QJsonArray rankingScoreArray;
    for (int i = 0; i < 5; i++)
        rankingScoreArray.push_back(QJsonValue::fromVariant(QVariant(highscoreValue[i])));
    recordObject.insert("Ranking Value", rankingScoreArray);

    QJsonDocument doc(recordObject);
    file.write(doc.toBinaryData());
}

I've filled the arrays like this, for debugging purposes

highscoreName[0] = "Pippo"; highscoreValue[0] = 100;
highscoreName[1] = "Franco"; highscoreValue[1] = 300;
highscoreName[2] = "Giovanni"; highscoreValue[2] = 200;
highscoreName[3] = "Andrea"; highscoreValue[3] = 4000;
highscoreName[4] = "AI"; highscoreValue[4] = 132400;

I tried to do a hexdump and the result is the following

0000-0010:  71 62 6a 73-01 00 00 00-a4 00 00 00-05 00 00 00  qbjs.... ........
0000-0020:  9c 00 00 00-14 04 00 00-0c 00 52 61-6e 6b 69 6e  ........ ..Rankin
0000-0030:  67 20 4e 61-6d 65 00 00-48 00 00 00-0a 00 00 00  g.Name.. H.......
0000-0040:  34 00 00 00-05 00 50 69-70 70 6f 00-06 00 46 72  4.....Pi ppo...Fr
0000-0050:  61 6e 63 6f-08 00 47 69-6f 76 61 6e-6e 69 00 00  anco..Gi ovanni..
0000-0060:  06 00 41 6e-64 72 65 61-02 00 41 49-8b 01 00 00  ..Andrea ..AI....
0000-0070:  8b 02 00 00-8b 03 00 00-0b 05 00 00-0b 06 00 00  ........ ........
0000-0080:  94 0f 00 00-0d 00 52 61-6e 6b 69 6e-67 20 56 61  ......Ra nking.Va
0000-0090:  6c 75 65 00-20 00 00 00-0a 00 00 00-0c 00 00 00  lue..... ........
0000-00a0:  8a 0c 00 00-8a 25 00 00-0a 19 00 00-0a f4 01 00  .....%.. ........
0000-00ac:  0a a6 40 00-0c 00 00 00-68 00 00 00              ..@..... h...

how to obtain c++ chrono microseconds based on double instead of integer [duplicate]

in the following code the Random::get() is a function that returns a random number in range [0, 1). The compiler screams on third line that integer is required. How to make it accepting a double?

double const timeFluctuationAmplitudeMicroseconds = 5000;
double timeFluctuationMicroseconds = timeFluctuationAmplitudeMicroseconds * Random::get();
auto abc = std::chrono::milliseconds(timeFluctuationMicroseconds);

How comes std::packaged_task is making a copy of my forwarded reference parameter?

#include <functional>
#include <iostream>
#include <future>

template <typename Func, typename... Args>
auto exec(Func&& func, Args&&... args)
  -> std::shared_ptr<std::packaged_task<typename std::result_of<Func(Args...)>::type()>> {
  using PackedTask = std::packaged_task<typename std::result_of<Func(Args...)>::type()>;
  func(args...);
  auto task = std::make_shared<PackedTask>(
      std::bind(std::forward<Func>(func), std::forward<Args>(args)...));
  return task;
}

int main() {
  auto i = 10;
  auto func = [](int& i) {
    std::cout << i << "\n";
  };
  i = 20;
  auto task = exec(func, i);
  i = 30;
  (*task)();
  return 0;
}

Compiled with g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)

g++ test.cpp -pthread

produces

$ ./a.out
20
20

I am experiencing with std::packaged_task and I do not understand why the i variable ends up being copied and how to avoid doing so while still passing it as an argument of my exec() function.

grid not showing (it is all black)

I didn't want to go back to the same question from yesterday, however before I am able to use the function to turn on and off the grid, I first need to know if my grid is actually working, I have been making new projects all night trying to display the grid but it isn't showing, the screen is always black and nothing is there at all.

#include "include\freeglut.h"   // OpenGL toolkit - in the local shared folder
#include <iostream>

//set up some constants
#define X_CENTRE 0.0      /* centre point of square */
#define Y_CENTRE 0.0
#define LENGTH   1.0      /* lengths of sides of square */

GLfloat red = 1.0, green = 1.0, blue = 1.0;
int w;
int h;

/* reshape callback function
executed when window is moved or resized */
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
/* uses orthographic (parallel) projection
use xmin = -1, xmax = 1
ymin = -1, ymax = 1
znear = -1, zfar = 1 - not relevant here (2D) */
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
}


/* display callback function
called whenever contents of window need to be re-displayed */
//this is the all important drawing method - all drawing code goes in here
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);   /* clear window */
//glColor3f(red, green, blue);        /* white drawing objects */
glColor3f(0.8, 0.8, 0.8);

GLint i;

glEnable(GL_LINE_STIPPLE); //Activates the line-style feature

glLineStipple(1, 0xAAAA);  // Plots a dashed polyline

glBegin(GL_LINES);
for (i = 2; i <= 9; i++)
{
    glVertex3f(i * 0.1 * w, 0.0, 0.0);
    glVertex3f(i * 0.1 * w, 0.9 * h, 0.0);
}

for (i = 1; i <= 9; i++)
{
    glVertex3f(0.1 * w, i * 0.1 * h, 0.0);
    glVertex3f(w, i * 0.1 * h, 0.0);
}
glEnd();
glDisable(GL_LINE_STIPPLE);

glFlush();     /* execute drawing commands in buffer */
}

/* graphics initialisation */
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);   /* window will be cleared to black */
}

//rename this to main(...) and change example 2 to run this main function
int main(int argc, char** argv)
{
/* window management code ... */
/* initialises GLUT and processes any command line arguments */
glutInit(&argc, argv);
/* use single-buffered window and RGBA colour model */
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
/* window width = 400 pixels, height = 400 pixels */
glutInitWindowSize(400, 400);
/* window upper left corner at (100, 100) */
glutInitWindowPosition(100, 100);
/* creates an OpenGL window with command argument in its title bar */
glutCreateWindow("Example 1");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);

glutMainLoop();
return 0;
}

missing ';' before 'boost::interprocess::offset_t' and missing type specifier - int assumed (boost 1.74.0, Visual Studio 2013) [duplicate]

I have an issue compiling code for a c++ project using the boost library. Everything works as expected with Visual Studio 2019, however, I also need this to work with Visual Studio 2013 in another branch of the same product.

Here's an example header (redacted):

#pragma once

#include <boost/interprocess/managed_windows_shared_memory.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/container/scoped_allocator.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/range/algorithm/find.hpp>
#include <memory>
#include <string>

#include <REDACTED.h>
#include <REDACTED2.h>

static constexpr boost::interprocess::offset_t SHARED_MEMORY_SIZE_IN_BYTES = 300000;

Compiling this in visual studio 2019 works without problems. But with 2013, I get the following:

error C2143: syntax error : missing ';' before 'boost::interprocess::offset_t' error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

Can someone explain to be what could go wrong in this case? Is boost incompatible with vs13? It is a header-only library, so I've simply used the same header files in both 2019 and 2013 versions of the product.

Another stack overflow question: Boost includes wreaks havoc - but it's not Boost's fault mentions that the order of the headers might be at fault, so I tried moving about my REDACTED.h and REDACTED2.h, but the error still occurs.

Another question: Building boost with Visual Studio 2013 (Express) mentions that there's been bugs in boost 1.55 related to visual studio 2013, but that they should be fixed. I assume 1.74.0 should include such fixes, but perhaps I need to apply some patch to 1.74.0 headers too, to get this working?

Is there an equivalent utility class for ByteArrayDataInput and ByteArrayDataOutput in C++?

I am doing some networking, and I need some organization in my packets. Sending raw bytes and having no abstraction is real difficult.

For java developers, do you know equivalent classes to ByteArrayDataInput and ByteArrayDataOutput in C++?

If you aren't familiar with them, could you show me how I could go about coding them.

#pragma once
#include <string>
class packetreader
{
public:
    bool read_bool(int index);

    char read_byte(int index);

    short read_short(int index);

    int read_int(int index);

    long read_long(int index);

    float read_float(int index);

    double read_double(int index);

    std::string read_string(int index);
};
#pragma once
#include <string>
class packetwriter
{
    void write_bool(int index, bool value);

    void write_byte(int index, char value);

    void write_short(int index, short value);

    void write_int(int index, int value);

    void write_long(int index, long value);

    void write_float(int index, float value);

    void write_double(int index, double value);

    void write_string(int index, std::string value);
};

Those are my header files, I now need help implementing them. And how could I go about efficiently reading/writing arrays of these types? like write_double_array(array) and read_double_array(array)? Writing it with write_double(array[i]) for every element in the array? Thanks.

clang-tidy readability-non-const-parameter warning, why?

I ran into an clang-tidy warning I don't understand. I've created a minimum example:

test.cpp:

#include <array>
#include <cstddef>

extern size_t get_data(float*const* buffers, size_t count);

size_t get_data_2_a(float* buffer1, float* buffer2)
{
  const std::array<float*, 2> buffers{buffer1, buffer2};
  return get_data(buffers.data(), buffers.size());
}

size_t get_data_2_b(float* buffer1, float* buffer2)
{
  float* buffers[] = {buffer1, buffer2};
  return get_data(buffers, sizeof(buffers) / sizeof(*buffers));
}

Running clang-tidy with:

clang-tidy -checks=readability-non-const-parameter test.cpp

clang-tidy output:

test.cpp:6:28: warning: pointer parameter 'buffer1' can be pointer to const [readability-non-const-parameter]
size_t get_data_2_a(float* buffer1, float* buffer2)
                           ^
                    const 
test.cpp:6:44: warning: pointer parameter 'buffer2' can be pointer to const [readability-non-const-parameter]
size_t get_data_2_a(float* buffer1, float* buffer2)
                                           ^
                                    const 

I've added those const's just to see what happens, clang-tidy still issues warnings:

test.cpp:6:34: warning: pointer parameter 'buffer1' can be pointer to const [readability-non-const-parameter]
size_t get_data_2_a(float* const buffer1, float* const buffer2)
                                 ^
                    const 
test.cpp:6:56: warning: pointer parameter 'buffer2' can be pointer to const [readability-non-const-parameter]
size_t get_data_2_a(float* const buffer1, float* const buffer2)
                                                       ^
                                          const 

clang-tidy version:

LLVM (http://llvm.org/):
  LLVM version 10.0.0
  
  Optimized build.
  Default target: x86_64-pc-linux-gnu
  Host CPU: znver2

I've tested it also using clang-tidy (trunk) at https://godbolt.org/z/P9xcEK

It only raises warning when using std::array, not when using a classic c-style array. What am I missing?

jeudi 26 novembre 2020

Maximum Diameter [closed]

You are given a tree of N+1 levels from 0 to N .There is only one node at the level 0 that is called as root. There is an array CNT of size N where CNT[i] denotes the number of nodes at ith level. You have to find the maximum diameter possible in such a tree.

Note: Diameter is the number of edges in the longest path of a tree.

#include<bits/stdc++.h>
using namespace std;
 
int Max_dia (int N, vector<int> CNT_i) {
   // Write your code here
   
}
 
int main() {

    int T;
    cin >> T;
    for(int t_i = 0; t_i < T; t_i++)
    {
        int N;
        cin >> N;
        vector<int> CNT_i(N);
        for(int i_CNT_i = 0; i_CNT_i < N; i_CNT_i++)
        {
            cin >> CNT_i[i_CNT_i];
        }
 
        int out_;
        out_ = Max_dia(N, CNT_i);
        cout << out_;
        cout << "\n";
    }
}

Can I use smart pointer with a mutex member?

Say I have a dynamic allocated object foo which have a std::mutex member:

#include <mutex>
#include <memory>

class foo {
    public:
        foo()=default;
        ~foo();
    private:
        std::mutex lock;
};

int main(){
    std::unique_ptr<foo> a = std::make_unique<foo>(foo());
    return 0;
}

I've tried to use a smart pointer, but it make no sense:

rog.cc:4:7: error: use of deleted function 'std::mutex::mutex(const std::mutex&)'
In file included from /opt/wandbox/gcc-head/include/c++/11.0.0/mutex:43,
                 from prog.cc:1:
/opt/wandbox/gcc-head/include/c++/11.0.0/bits/std_mutex.h:94:5: note: declared here
   94 |     mutex(const mutex&) = delete;
      |     ^~~~~

shall I must use raw pointer to manage this object?

std::_Rb_tree_const_iterator

when I loop a map use for(auto),then crash. Dump Info,

std::_Rb_tree_increment(std::_Rb_tree_node_base const*) () from /lib64/libstdc++.so.6 std::_Rb_tree_const_iterator<std::pair<int const, OTSOrderField> >::operator++.

As this crash which I am getting is not reproducible and the inside code is complex to discuss it here(as calling functions). Can someone suggest to get the same core with the help of sample program for map. It will be very helpful for me to debug that way.

Best data structure to create buffer for plotting [closed]

I have an external app that outputs to stdout in real-time, and I'm trying to create a UI for that app with QT and qcustomplot.

I'm doing real-time plotting however I noticed that adding each point does not work well enough, so I found that a solution would be to use a buffer and replot n points at once according to this link:

https://www.qcustomplot.com/index.php/support/forum/704

My current code looks like this:

void    Monitor::readyReadStandardOutput(){

    QProcess *p = (QProcess *)sender();
    // get the data
    QByteArray buf = p->readAllStandardOutput();
    QList<QByteArray>  buf_res =   ((buf.split(','))[1]).split('\n');

    double d= (buf_res[0]).toDouble() ;
    this->win->queue.enqueue(d); // here we're adding the new point to a queue in our window

}

Then in my mainwindow

void MainWindow::realtimeDataSlot2(){
    if (queue.size() == 0 ) return;
    double val = queue.dequeue() ;
    double key = time.elapsed()/1000.0; 
    static double lastPointKey = 0;
    if (key-lastPointKey > 0.02) // at most add point every 2 ms
    {
     ui->customPlot->graph(0)->addData(key, val );
     lastPointKey = key;
    }
    ui->customPlot->xAxis->setRange(key, 8, Qt::AlignRight);
    ui->customPlot->replot();

}

addData's arguments can be replaced with a vector, so I'm looking for something that looks like this.

  1. Change the queue to a "buffer" (but which QT/C++ type exactly)?

  2. In the reading function we need to replace the enqueue of 1 element to pushing multiple elements at once to some buffer

  3. In the plotting function extracting the first 1000 points from the buffer into a QVector<double>.

I'm a bit confused on how to achieve this and what types to use exactly that allow adding multiple elements and extracting multiple elements easily and efficiently.

Passing a std::shared_ptr

I have a function that needs to take shared ownership of an argument, but does not modify it. I have made the argument a shared_ptr<const T> to clearly convey this intent.

template <typename T>
void func(std::shared_ptr<const T> ptr){}

I would like to call this function with a shared_ptr to a non-const T. For example:

auto nonConstInt = std::make_shared<int>();
func(nonConstInt);

However this generates a compile error on VC 2017:

error C2672: 'func': no matching overloaded function found
error C2784: 'void func(std::shared_ptr<const _Ty>)': could not deduce template argument for 'std::shared_ptr<const _Ty>' from 'std::shared_ptr<int>'
note: see declaration of 'func'

Is there a way to make this work without:

  • Modifying the calls to func. This is part of a larger code refactoring, and I would prefer not to have to use std::const_pointer_cast at every call site.
  • Defining multiple overloads of func as that seems redundant.

We are currently compiling against the C++14 standard, with plans to move to c++17 soon, if that helps.

How the code is working ? what is the work of array a[5]?

enter image description herewhy there is a[5] and what is the work of it? also if I input more than 5 values how its work?? can any one help me out and go through the code . TIA

template constexpr endian converter (without UB)

I have seen some other answers that propose to use unions for byte swapping (which is UB or can't be done at compile time).

I've wrote mine, and it kind of worked until I have met some case which have shown that my implementation is invalid. I can't spot a mistake, can you help me?

namespace impl
    {
        constexpr bool native_is_big_endian()
        {
            return bool(uint16_t(1) >> 8u);
        }
    }

    /*!
     * \brief std compliant type for endianness
     * \details
     * If all scalar types are little-endian, endian::native equals endian::little
     * If all scalar types are big-endian, endian::native equals endian::big
     */
    enum class endian
    {
        little,
        big,
        native = impl::native_is_big_endian() ? big : little
    };

    template<typename T>
    class swap_endian
    {
        constexpr static size_t sz_minus_one = sizeof(T) - 1;
        template<size_t> struct tag_s
        {
        };

        constexpr static T bitwise_or(tag_s<0>, T original, T res)
        {
            return res | (original >> sz_minus_one * 8);
        }

        template<size_t i>
        constexpr static T bitwise_or(tag_s<i>, T original, T res)
        {
            return bitwise_or(tag_s<i - 1>(), original, original << i * 8 >> sz_minus_one * 8 << i * 8);
        }

    public:
        constexpr static T swap(T u)
        {
            return bitwise_or(tag_s<sz_minus_one>(), u, 0);
        }
    };

    template<typename T>
    constexpr T swap_endian_v(T u)
    {
        return swap_endian<T>::swap(u);
    }

    template<endian From, typename T>
    constexpr T to_native_endian(T u)
    {
        return From == endian::native ? u : swap_endian_v(u);
    }

int main()
{
    static_assert(uint8_t(0xFA) == swap_endian_v(uint8_t(0xFA)), "Invalid result for endian swapping");
    static_assert(uint16_t(0x00AA) == swap_endian_v(uint16_t(0xAA00)), "Invalid result for endian swapping");
    static_assert(uint16_t(0xF0AA) == swap_endian_v(uint16_t(0xAAF0)), "Invalid result for endian swapping");
    static_assert(uint32_t(0x00'00'CC'00) == swap_endian_v(uint32_t(0x00'CC'00'00)),
                  "Invalid result for endian swapping");

// this fails
//    static_assert(uint32_t(0x6A'25'65'75) == swap_endian_v(uint32_t(0x75'65'25'6A)),
//                  "Invalid result for endian swapping");
    return 0;
}

Please, don't suggest to use BOOST. At this point I am very interested in finding out what kind of mistake I've made in the algorithm.

How to make a static template member function as friend

I would like to define a staitc member funtion to build my class. This staitc function would access private member, and I make it as friend.

Here is the demo code:

#include <memory>

template<typename T>
class Foo
{
public:
    static std::unique_ptr<Foo> Create();

    friend static std::unique_ptr<Foo> Foo::Create();
};

template<typename T>
std::unique_ptr<Foo<T>> Foo<T>::Create()
{
    return std::unique_ptr<Foo<T>>();
}

template class Foo<int>;
template class Foo<double>;


int main()
{
    return 0;
}

It compiles faild. How to fix it?

How can I get keys set from map or unordered_map in c++?

I want to get all keys from a collection, is there a standard way to do this?

std::unordered_map<std::string, size_t> map;
auto keys = map.get_keys();

combine allocation/construction Or deallocation/destruction with custom raw memory provision

I need to provide a utility function where both memory allocation and object construction take place and the user gets the pointer in return. Similarly, there is a need to provide a utility function for deallocation and destruction also.

Here is what I implemented: (I have not implemented for array type though)

#include <cstdlib> // for malloc
#include <iostream> // for cout
#include <string>  // for memset

// C++ class with some initial state x = 10
class SomeClass {
    public:
    SomeClass() : x(10) {}
    int x = 0;
};

template<typename T, typename ... Args>
inline T* MY_MODULE_NEW(Args&&... args) {
    // some custom allocator logic here which allocates just raw memory
    // for example purpose just use malloc
    void *p = malloc(sizeof(T));
    memset(p,0,sizeof(T));
    T* t = new(p) T(std::forward<Args>(args)...);
    return t;
}

template<typename T>
inline void MY_MODULE_DELETE(T* ptr) {
    ptr->~T();
    // some custom allocator logic here, which deallocates raw memory
    // for example purpose just use free
    free(ptr);
}

int main() {
    SomeClass* sc = MY_MODULE_NEW<SomeClass>();
    std::cout << sc->x << std::endl;

    SomeClass* sc2 = MY_MODULE_NEW<SomeClass>(*sc);
    std::cout << sc2->x << std::endl;

    MY_MODULE_DELETE(sc);
    MY_MODULE_DELETE(sc2);
}

I have the following concerns:

  1. From the performance point of view, Is this inline function good enough? Can we do better?
  2. Personally I feel MY_MODULE_NEW<SomeClass>(...) syntax is almost similar to the canonical syntax for operator new which is new SomeClass(). Is there any other idiomatic way to achieve the same result?

Thank You!

Can't use "{}" inside of "?" [duplicate]

Why can't braces initialization operator be used inside of '?' operator?

Am I missing something?

std::function<bool(int,int)> sortfn()
{
    return {};
}

int main(int argc, char *argv[])
{
    bool b = false;
    //auto fn = sortfn();  // compiles OK
    auto fn = b ? sortfn() : {}; // compilation error: syntax error: '{'

    return 0;
}

Fast memory allocation of big memory chunk

I've been measuring the performance of different C/C++ allocation (and initiation) techniques for big chunks of continuous memory. To do so, I tried to allocate (and write to) 100 randomly selected sizes, using uniform distribution and range of 20 to 4096 MB, and measured the time using std::chrono high_resolution_clock. Each measurement is done by a separate execution of a program, i.e. there should be no memory reuse (at least within the process).

madvise ON refers to calling madvise with MADV_HUGEPAGE flag, i.e. enabling transparent huge pages (2MB in case of my systems).

Using a single 16GB module of DDR4 with a clock speed of 2400 MT/s and a data width of 64 bits, I've got a theoretical maximal speed of 17.8 GB/s.

On Ubuntu 18.04.05 LTS (4.15.0-118-generic), memset of the already allocated memory block gets close to the theoretical limit, but the page_aligned allocation + memset is somewhat slower, as expected. New() is very slow, probably due to its internal overhead (values in GB/s):

method              madvise     mean    std
memset              madvise OFF 17.3    0.32
page_aligned+memset madvise ON  11.4    0.21
mmap+memset         madvise ON  11.3    0.23
new<double>[]()     madvise ON  3.2     0.06

Using two modules, I was expecting near to double performance (say 35 GB/s) due to dual-channel, at least for the write operation:

method              madvise     mean    std
memset              madvise OFF 28.0    0.23
mmap+memset         madvise ON  14.5    0.18
page_aligned+memset madvise ON  14.4    0.17

How you can see, memset reaches only 80% of the theoretical speed. Memory allocation + write speed increases only by 3 GB/s, reaching only 40% of the theoretical speed of the memory.

To make sure that I did not mess up something in the OS (I use it for a few years now), I installed fresh Ubuntu 20.04 (dual boot) and repeated the experiment. The fastest operations were these:

method              madvise     mean    std
memset              madvise OFF 29.1    0.86
page_aligned+memset madvise ON  10.5    0.27
mmap+memset         madvise ON  10.5    0.31

As you can see, the results are reasonably similar for memset, but actually even worse for allocation + write operations.

Are you aware of a faster way of allocating (and initializing) big chunks of memory? For the record, I have tested combinations of malloc, new<float/double>, calloc, operator new, mmap and page_aligned for allocation, and memset and for loop for writing, together with the madvise flag.

mercredi 25 novembre 2020

Core dump error when using an ifstream as parameter

I was working on the Calculator problem provided in Bjarne Stroustrup's book - Programming Principles and Practice Using C++. An exercise stated to modify a class to use an istream as an explicit parameter, to allow input from a file. The code works if I pass cin to the function. Howerver, if I give it an ifstream, the program does what it's supposed to do, then exits with a segmentation fault. Here's the main() function:

#include "std_lib_facilities.h"
#include "token.h"
#include "variable.h"
#include "calculator.h"

//NOTE: The Token_stream works with files, but not fully:
    //it reads from them, does the correct calculations, but then crashes with a a core dump error, double free or corruption (out)
ifstream istr;

Token_stream ts(istr);
Symbol_table st;
void initialize_custom_variables();

int main()
{
    istr.open("input.txt");
    initialize_custom_variables();
    intro_message();
    calculate(ts, st);
    istr.close();
    return 0;
}

void initialize_custom_variables()
{
    st.define_variable("pi", 3.14159, true);
    st.define_variable("e",2.71828 , true);
}

Here are the header files used:

token.h

#pragma once
#include "std_lib_facilities.h"
//Token implementation----------------------------------------------------------
class Token {
public:
    char type;
    double value;
    string name;   // used for a Token of type name

    Token(char ch) :type{ ch }, value{ 0 } {};
    Token(char ch, double val) :type{ ch }, value{ val } {};
    Token(char ch, string n) :type{ ch }, name{ n } {};
};
//-------------------------------------------------------------------------------

//Token_stream implementation----------------------------------------------------
class Token_stream {
public:
    Token_stream(istream& istr);
    Token get();
    void putback(Token t);
    void ignore(char c);

private:
    bool isFull;
    Token buffer;
    istream& istr_p;
};

variable.h

#pragma once
#include "std_lib_facilities.h"

//Variable implementation--------------------------------------------------------
class Variable
{
public:
    std::string name;
    double value;
    bool isConst;

    Variable(std::string st, double v, bool b) : name{ st }, value{ v }, isConst{ b } {}
    Variable(std::string st, double v) : name{ st }, value{ v }, isConst{ false } {}
};

class Symbol_table
{
public:
    double get_value(std::string s);
    void set_value(std::string s, double n); //We all have our daemons, running in the background without us realising it.
    bool is_declared(std::string var);
    double define_variable(std::string var, double val, bool isConst);
    void show_variables();

private:
    vector <Variable> var_table;
};

calculator.h

#pragma once
// forward declarations
//class Token_stream;
//class Symbol_table;
#include "token.h"

//Declarations and Initializations-----------------------------------------------
void calculate(Token_stream& ts, Symbol_table& st);
double statement(Token_stream& ts, Symbol_table& st);
double declaration(Token_stream& ts, Symbol_table& st);
double square_root(Token_stream& ts, Symbol_table& st);
double powerf(Token_stream& ts, Symbol_table& st);
double expression(Token_stream& ts, Symbol_table& st);
double term(Token_stream& ts, Symbol_table& st);
double factorial(Token_stream& ts, Symbol_table& st);
double primary(Token_stream& ts, Symbol_table& st);
double variable(Token_stream& ts, Symbol_table& st);
void intro_message();
void cleanup(Token_stream&);
//-------------------------------------------------------------------------------

Compilation error “room.cpp:37:14: error: ‘Room’ has not been declared”

I am trying to compile this cpp file, yet it prints out following error message.

room.cpp:21:1: error: ‘Room’ does not name a type Room::Room()

I have applied solutions that are already provided online. Could you please guide me what to do?? It may be the order of "include library"?

enter image description here

#include <stdio.h> 
#include <stdlib.h>                                                                                                                        
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <cstdint>
#include <iostream>
#include <list>
#include <algorithm>
#include "server.cpp"
#include "client.cpp"
#include "room.h"
#include "errorHandler.cpp"

// TODO: if errorHandler contains some libraries, does that inherit to the current cpp file as well?
// TODO: Make sure that the constructor works
// If Room is created without RoomNo, create Lounge

class Room(){

public: 
    Room(); 
    Room(int RoomNo);
    
    enter(Client client);

private:
    int RoomNo;
    Client client;
}


Room::Room()
{
    Lounge* lounge;
}

// If Room is created with RoomNo, create ChatRoom with RoomNo
Room::Room(int RoomNo);
{
    ChatRoom* chatRoom(RoomNo);
}

virtual void Room::enter(Client client)
{
    bool foundClient = (std::find(client_list.begin(), client_list.end(), client) != client_list.end());
    if (foundClient) {
        std::set_unexpected(errorHandler::room_unexp);
        try {
            errorHandler::room_bad_exception();
        } catch(const std::bad_exception& e) {
            std::cerr << "Caught " << e.what() << "\n";
        }

    } else {
        client_list.push_back(client);
        enterExitMessage(client, true);
    }
};

I want to know how to fix the error I mentioned above!

grid not showing at all when I try to on it

I am trying to make an option pop-up menu to be able to choose if I want the grid on or off as an option to add to the game I am trying to make. I have been able to display the pop-up menu which has two options called "grid on" and "grid off", however when I click on it, the grid doesn't show at all for me which I am struggling to do.

void myGrid(GLint i) {
glEnable(GL_LINE_STIPPLE); //Activates the line-style feature

glLineStipple(1, 0xAAAA);  // Plots a dashed polyline

glColor3f(0.8, 0.8, 0.8);

glBegin(GL_LINES);
for (i = 2; i <= 9; i++)
{
    glVertex3f(i * 0.1 * w, 0.0, 0.0);
    glVertex3f(i * 0.1 * w, 0.9 * h, 0.0);
}

for (i = 1; i <= 9; i++)
{
    glVertex3f(0.1 * w, i * 0.1 * h, 0.0);
    glVertex3f(w, i * 0.1 * h, 0.0);
}
glEnd();
glDisable(GL_LINE_STIPPLE);
}

int main(int argc, char* argv[])//standard c entry signature
{
//cout << "Player Controls:\n Up Key - move forward\n Down Key - move backward\n Left/Right key - move left or right\n R/r - rotate";
/* window management code ... */
/* initialises GLUT and processes any command line arguments */
glutInit(&argc, argv);
/* use double-buffered window and RGBA colour model */
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
/* window width = 400 pixels, height = 400 pixels */
glutInitWindowSize(500, 500);
/* window upper left corner at (100, 100) */
glutInitWindowPosition(100, 100);
/* creates an OpenGL window and set its title bar*/
glutCreateWindow("Coursework 1");
init();

glutDisplayFunc(display);

//glutKeyboardFunc(keyboard);
//glutSpecialFunc(specialKeys);
//  glutSpecialUpFunc(keyGoneUp);

glutReshapeFunc(reshape);

//Create a grid turning it on and off
glutCreateMenu(myGrid);

glutAddMenuEntry("Grid on", 1);
glutAddMenuEntry("Grid off", 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
//  SetupRC();
glutIdleFunc(IdleFunc);
glutMainLoop();

return 0;
}

Remove a list item from list in the item's member function (C++ STL)

Say I have a list list<Item>, and

class Item {
 public:
  Item(list<Item>& l); // l is the list the item is in.

  RemoveItself() {...} // remove this from l.
}

when I call item.RemoveItself(), it remove itself from the list. If I were to implement myself, I could have prev_ptr and next_ptr in the Item, and then everything is easy. I am wondering if there is a way to do it using STL?

Thanks!

Strange Output in Selection Sort using C++ min_element()?

I have implemented this code myself for Selection Sort after understanding the logic. You can clearly see I have used C++ STL's min_element() to find the minimum element in the array. But the Output is Completely Wrong. It seems as if the forward iterator first for min_element() is not iterating. Can someone help me finding the underlying problem. Thanks in Advance !

#include<iostream>
#include<algorithm>


using namespace std;

void Swap(int &a,int &b){
    a=a+b;
    b=a-b;
    a=a-b;
}


void SelectionSort(int arr[],int n){
    int Min;
   
    for(int i=0;i<n-1;i++){

        Min=*min_element(arr+i,arr+n);
      
        Swap(arr[i],Min);
        
       
    }
    for(int i=0;i<n;i++){
        cout<<arr[i]<<" ";
    }
    
}

int main(){
    int arr[]={64, 25, 12, 22, 11};
    int n=sizeof(arr)/sizeof(arr[0]);
    SelectionSort(arr,n);
    return 0;
}

OUTPUT :

11 11 11 11 11

What is move() in c++98? [closed]

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

int main(void){

 vector<int> a;
 a.push_back(3);
 vector<int> b = move(a);
 cout<<"b: "<<b.data()<<endl;
 cout<<"a: "<<a.data()<<endl;

 return 0;
}

Output(in c++98):

b: 0x7f9a82405730

a: 0x7f9a82405720

Output(in c++11):

b: 0x7f9a82405730

a: 0x0

I am using clang.

No compiler flags are used for the second output.

-std=c++11 flag for the second output.

I know what move() does in c++11 (and higher versions). But as I can see using move() in c++98 does nothing to the object passed and just deep copy happens.

Then why is there a move() in c++98??

Are there any downside to using `std::reference_wrapper

I am having a quite common problem, I have a class that must store a non-owning pointer to a different class object.

I know that:

  • The lifetime of the reference object is guaranteed to outlive the instance.
  • The referenced object is passed in a constructor and does not change with the exception of moves or assignment.
  • It is never invalid.
  • It is used in many methods.
  • It can be shared by many instances.

Think of e.g. a logger class which is not global.

These points lead me to this solution using a reference variable which guarantees validity:

struct Foo{};

struct Bar{
    Bar(Foo& foo):m_foo(foo){}

Foo& m_foo;
};

The big downside is Bar is unnecessarily almost immutable - no assignment, no move.

The usual thing I did was to store Foo as a pointer instead. This solves most of the issues except that it is no longer very clear that the pointer is always valid. Furthermore it adds a new small one that it can be invalidated in any method, which should not happen. (Making it const has the same downside as &). That makes me add assert(m_foo) to every method for the peace of mind.

So, I was thinking about just storing std::reference_wrapper<Foo>, it is always valid and it keeps Bar mutable. Are there any downsides compared to a simple pointer? I know that any method can still point it to e.g. a local variable but let's say that does not happen because it is perhaps hard to obtain a new valid instance of Foo. At least it is harder than simple =nullptr;

I know this approach is used for containers like std::vector so I assume it is okay, but I would like to know if there is any catch I should look for.

clang compiling to which version of c++ in macOS?

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

    int main()
    {
     vector<int> a;
     a.push_back(3);
     vector<int> b = move(a);
     cout<<"b: "<<b[0]<<endl;
    }

As far as I know, "move semantics" is a part of c++11

Output: C++98 (when compiled with clang++ command without any flags)

Then how are the move semantics working??

I know that I can select the particular version of c++ I want to compile to with the -std=c++xx flag, but that's not what I want.

I want to know, what is the default version of c++ to which clang compiles to in macOS ?

How to detect universal reference parameter type with std::is_same

Have a look at these lines:

template <typename T>
void f(T&& param) {
    if (std::is_same<T, int>::value) {
        cout << "param is an int" << endl;
    } else {
        cout << "param is not an int" << endl;
    }
    if (std::is_same<T, int&>::value) {
        cout << "param is an lvalue reference to int" << endl;
    }
    if (std::is_same<T, int&&>::value) {
        cout << "param is an rvalue reference to int" << endl;
    }
}
int main() {
    int i = 0;
    f(i);
    f(std::move(i));
    return 0;
}

The first function call f(i) yields:

param is not an int

param is an lvalue reference to int

which is what I expected, because as per the template argument deduction rules, T resolves to T&, resulting in T&& & which yields T& because of reference collapsing.

The second funtion call f(std::move(i)) yields

param is an int

which is not what I expected. I'd have expected

param is an rvalue reference to int

or at least

param is not an int

Can someone explain why my expectations regarding the second function call are not met ?

How to detect universal reference parameter type with std::is_same

Have a look at these lines:

template <typename T>
void f(T&& param) {
    if (std::is_same<T, int>::value) {
        cout << "param is an int" << endl;
    } else {
        cout << "param is not an int" << endl;
    }
    if (std::is_same<T, int&>::value) {
        cout << "param is an lvalue reference to int" << endl;
    }
    if (std::is_same<T, int&&>::value) {
        cout << "param is an rvalue reference to int" << endl;
    }
}
int main() {
    int i = 0;
    f(i);
    f(std::move(i));
    return 0;
}

The first function call f(i) yields:

param is not an int

param is an lvalue reference to int

which is what I expected, because as per the template argument deduction rules, T resolves to T&, resulting in T&& & which yields T& because of reference collapsing.

The second funtion call f(std::move(i)) yields

param is an int

which is not what I expected. I'd have expected

param is an rvalue reference to int

or at least

param is not an int

Can someone explain why my expectations regarding the second function call are not met ?

Can I forbid calling private member of derived class from base?

I has this code:

struct A {
  virtual void f() {}
};
struct B: A {
 private:
  void f() override {}
};
...
B b;
A& a = b;
a.f();

And ofcourse it will call f() from B cause private is checked on the compilation time but choosing virtual function version are in the runtime. Can I forbid f() calling in this case?

Issue Integrating MySQL Connector C++ with another Library: Segmentation Fault on get_driver_instance()

I use MySQL-Connector-C++ along with a third party library whose executable causes a segmentation fault on sql::Driver* driver = get_driver_instance();.

My main.cpp has two parts.

  • It calls into my_MySQL_utilities class that can read and write to a local MySQL database.
  • main.cpp also calls into a third party library through my_MySQL_utilities that connects to a server from which some external data is retrieved and is printed to stdout.

To track down the issue, I tried to de-couple the two parts and see if I can run them separately.

I can compile, link, and execute the MySQL part in my main.cpp (commenting out the third party part of main.cpp and excluding its source/header files). Reading and writing to the MySQL database is done successfully. I use the following CMakeLists.txt to create an executable to read from a local MySQL database:

# For MySQL-Connector-C++ Only, which compiles, links, and runs with no problem
cmake_minimum_required(VERSION 3.17)
project(myproject)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
add_library(libmysqlcppconn STATIC IMPORTED)
set_property(TARGET libmysqlcppconn PROPERTY IMPORTED_LOCATION /usr/lib/x86_64-linux-gnu/libmysqlcppconn.so)
set(SOURCE_FILES main.cpp my_MySQL_utilities.cpp my_MySQL_utilities.h)
add_executable(myproject ${SOURCE_FILES})
target_link_libraries (myproject libmysqlcppconn)

Similarly, I can compile, link, and execute the third party library in my main.cpp (commenting out the MySQL part of main.cpp and excluding its source/header files). Using this third party library, I can successfully read data from a server and print to stdout:

# For Third Party Library Only, which compiles, links, and runs with no problem
cmake_minimum_required(VERSION 3.17)
project(myproject)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -O3 -DLINUX -D_REENTRANT -Wall -Wno-sign-compare -Wno-write-strings -Wpointer-arith -Winline -Wno-deprecated -fno-strict-aliasing")
INCLUDE_DIRECTORIES(/home/thirdparty/include/)
link_directories(/home/thirdparty/lib/)
link_directories(/usr/lib/x86_64-linux-gnu/)
add_library(libthirdparty1 STATIC IMPORTED)
add_library(libthirdparty2 STATIC IMPORTED)
add_library(libthirdparty3 STATIC IMPORTED)
add_library(libthirdparty4 STATIC IMPORTED)
add_library(libssl STATIC IMPORTED)
add_library(libz STATIC IMPORTED)
add_library(libpthread STATIC IMPORTED)
add_library(librt STATIC IMPORTED)
add_library(libdl STATIC IMPORTED)
set(SOURCE_FILES main.cpp my_thirdpartylib_utilities.cpp my_thirdpartylib_utilities.h)
add_executable(myproject ${SOURCE_FILES})
target_link_libraries (myproject thirdparty1 thirdparty2 thirdparty3 thirdparty4 ssl z pthread rt dl)

However, when I have MySQL-Connector-C++ and the third party library both uncommented in main.cpp, MySQL-Connector-C++ will terminate with a segmentation fault on instantiating the driver:

sql::Driver* driver = get_driver_instance();

...

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Could someone kindly help me out?

mardi 24 novembre 2020

Getting "Incomplete Type" error when trying to create a new object in cpp file

This is my first time posting, so sorry if there's any issues with my formatting or wording.

As the title says, I've just been getting started working on an assignment and found an issue when trying to create an object instance of a class. I'm trying to create the object in a .cpp file that I'll be using for testing. The error is:

incomplete type not allowed

There are three files: Process.h, Process.cpp, and test.cpp. The code for each is below.

Process.h

#include <iostream>
#include <string>

using namespace std;

class Process {

private:

    int ProcessID;
    string ProcessState;


public:

    //constuctor
    Process(int, string);

    //mutator functions
    void SetProcessID(int);
    void SetProcessState(string);

    //accessor functions
    int GetProcessID();
    string GetProcessState();

};

Process.cpp

#include <iostream>
#include "Process.h"

//constructor
Process::Process(int Id, string State)
{
    SetProcessID(Id);
    SetProcessState(State);
}

//mutator
void Process::SetProcessID(int Id)
{
    ProcessID = Id;
    return;
}

//mutator
void Process::SetProcessState(string State)
{
    ProcessState = State;
    return;
}

//accessor
int Process::GetProcessID()
{
    return ProcessID;
}

//accessor
string Process::GetProcessState()
{
    return ProcessState;
}

Test.cpp

#include <iostream>
#include "Process.h"

using namespace std;

class Process;

int main()
{
    Process Process1(1, "Ready"); //Error here on this line

    cout << "Process 1 created" << endl;

}

I have tried to replace the error line in the test.cpp with this:

Process* Process1(1, "Ready");

or

Process Process1 = new Process(1, "Ready");

and variations of these. As well as trying to switch around the includes. But to no avail.

I'm working in Visual Studio 2019, and it seems that the test.cpp is aware of the Process class, but something (the constructor, maybe?) is out of its scope for some reason.

Running the test.cpp code in the Process.cpp file works as intended, but I need to be able to call it in other files.

The exact error, as seen is Visual Studio 2019, is E0070: incomplete type is not allowed

How do I implement a begin() member function in my custom data structure?

I'm trying to create my own data-structure that can determine if a value is an element within it in O(1) time with a hash-map.

I'm working on adding more member functions so that it's more similar to the STL containers. Here's what I currently have that's relevant to the problem:

template <class T>
class setfind {

private:
    long long _size = 0;
    unordered_map<T, bool> _set;

public:
    // constructors
    setfind() {}
    // initialize from some iterable
    template <class InputIterator>
    setfind(InputIterator beg, InputIterator en){
        _size = en - beg;
        while (beg != en){
            _set[*beg] = true;
            beg++;
        }
    }

    bool contains(const T &val){
        return _set[val];
    }
    bool contains(const T &&val){
        return _set[val];
    }
};

As you can see, its core is the unordered_map. I want to write a member function that returns a begin iterator to the _set variable. I tried putting this in:

template <class InputIterator>
InputIterator begin()
{
    return _set.begin();
}

but that led to a compilation error saying that there was no matching member function. I don't know enough about iterators and template-classes to fix this. Does anyone know how to implement it or what's wrong? Are there any good resources so that I can learn more about this?

Also some optimization tips for this class would be appreciated because this is going to be used under a time-limit.

EDIT: I’m restricted to using c++11 EDIT2: Fixed a bug in the constructor

Is it possible to execute "cout" by order?

is it possible to get the raw output as shown but with specific order(from bottom to top)?


cout<<R"(programming )";sleep(10); cout<<R"(
          newbie at  )";sleep(5); cout<<R"(
            i'm      )"; sleep(1);


output:  programming------>printed third
           newbie at------->printed second
            i'm--------->printed first

note: I don't mean reversing the output

breakpoint triggered after creation of 2nd object

I am building the game Snake using OpenGL in VS. I have my class that handles the models, VertexData, and then the rest of the game in Main. Whenever I create the first object by calling createModel(), everything works fine. However whenever I call createModel() the second time, like to create the apple, there is about a 40% chance of Visual Studio triggering a breakpoint. everytime I call createModel() after that, like to create another body segment, the chances of it triggering a breakpoint increases. Is it due to where I am creating the object, or is there something else wrong? I saw that adding a copy constructor to the VertexData class would stop the crashing but it did not.

Main.cpp:

//includes
#include "convertToFloat.h"
#include "vertexData.h"
#include <iostream>
#include <vector> 
#include <time.h>

//function prototypes
static void error_callback(int error, const char* description);
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void initWindow();
void destroy();
void changeLocation();
void update();
void render();
void loadModels();
void onStartUp();
void onCollect();
void createModel();
int roundUp(int numToRound, int multiple);
int roundDown(int numToRound, int multiple);

//object declerations
GLFWwindow* window;

//variables
int x = 200;
int y = 200;
int appleLoc[2] = { x,y };
int direction = 0;
int stepSize = 20;
bool start = false;
static double limitFPS = 1.0 / 15.0;
double lastTime = glfwGetTime(), timer = lastTime;
double deltaTime = 0, nowTime = 0;
int frames = 0, updates = 0;
std::vector<std::shared_ptr<VertexData>> models;

int main(void)
{
    initWindow();
    loadModels();
    onStartUp();
    while (!glfwWindowShouldClose(window))
    {
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        nowTime = glfwGetTime();
        deltaTime += (nowTime - lastTime) / limitFPS;
        lastTime = nowTime;
        while (deltaTime >= 1.0) {
            update();
            updates++;
            deltaTime--;
        }
        render();
        frames++;

        if (glfwGetTime() - timer > 1.0) {
            timer++;
            updates = 0, frames = 0;
        }
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    destroy();
}

void onCollect() {
    appleLoc[0] = roundUp(rand() % 620, 20);
    appleLoc[1] = roundUp(rand() % 460, 20);
    //models.at(1)->move(appleLoc[0], appleLoc[1]);
    //createModel();
}

void onStartUp() {
    srand(time(0));
    onCollect();
}

void createModel() {
    std::shared_ptr<VertexData> model{ new VertexData("models/snakeHead.md",640,480) };
    models.push_back(model);
}

void loadModels() {
    createModel();
    createModel();
}

void changeLocation() {
    switch (direction) {
        case(0):
            if(y<460)
                y += stepSize;
            break;
        case(1):
            if (x < 620)
                x += stepSize;
            break;
        case(2):
            if (y > 0)
                y -= stepSize;
            break;
        case(3):
            if (x > 0)
                x -= stepSize;
            break;
    }
    std::cout << x << " " << y << std::endl;
    std::cout << appleLoc[0] << " " << appleLoc[1] << std::endl;
}

void render() {
    for(int i=0; i<models.size();i++)
        models.at(i)->render();
}

void update() {
    if (start)
        changeLocation();
    models.at(0)->move(x, y);
    if (x == appleLoc[0] && y == appleLoc[1]) {
        onCollect();
    }
}

void initWindow() {
    if (!glfwInit())
        exit(EXIT_FAILURE);

    window = glfwCreateWindow(640, 480, "Snek", NULL, NULL);

    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window);
    gladLoadGL(glfwGetProcAddress); //important
    glfwSwapInterval(1);

    glfwSetErrorCallback(error_callback);
    glfwSetKeyCallback(window, key_callback);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
}

static void error_callback(int error, const char* description)
{
    fprintf(stderr, "Error: %s\n", description);
}

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GLFW_TRUE);
    if (key == GLFW_KEY_W && action == GLFW_PRESS) {
        direction = 0;
        start = true;
    }
    if (key == GLFW_KEY_S && action == GLFW_PRESS){
        direction = 2;
        start = true;
    }
    if (key == GLFW_KEY_A && action == GLFW_PRESS){
        direction = 3;
        start = true;
    }
    if (key == GLFW_KEY_D && action == GLFW_PRESS){
        direction = 1;
        start = true;
    }
}

int roundUp(int numToRound, int multiple)
{
    if (multiple == 0)
        return numToRound;

    int remainder = numToRound % multiple;
    if (remainder == 0)
        return numToRound;

    return numToRound + multiple - remainder;
}

int roundDown(int numToRound, int multiple)
{
    if (multiple == 0)
        return numToRound;

    int remainderInverseSorta = multiple-(numToRound % multiple);
    if (remainderInverseSorta == 0)
        return numToRound;

    return numToRound - multiple + remainderInverseSorta;
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

void destroy() {
    for (int i = 0; i < models.size(); i++)
        models.at(i)->destroy();
    glfwDestroyWindow(window);
    glfwTerminate();
    exit(EXIT_SUCCESS);
}

vertexdata.h:

#ifndef vertextData
#define vertexData

#define GLFW_INCLUDE_NONE
#include "loadFile.h"
#include "convertToFloat.h"
#include "shaderLoader.h"
#include <GLFW/glfw3.h>
#include <glad/gl.h> // include glad to get all the required OpenGL headers
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>


class VertexData {
    private:
        unsigned int VAO,VBO,EBO;
        int width = 0;
        int height = 0;

        std::unique_ptr <Shader> shader{ new Shader("Shaders/3.3.shader.vs", "Shaders/3.3.shader.fs") }; //add shader path to constructor
        glm::mat4 trans = glm::mat4(1.0f);
    public:
        VertexData(const char* modelPath,int width,int height);
        VertexData(const VertexData& data);
        void render();
        void move(int x, int y);
        void rotate(int deg);
        void destroy();
};
#endif

vertexData.cpp:

#include "vertexData.h"

VertexData::VertexData(const char* modelPath, int width, int height) {
    this->width = width;
    this->height = height;
    std::unique_ptr<ConvertToFloat> conversion{ new ConvertToFloat(width, height) };
    std::unique_ptr<LoadFile> file{ new LoadFile() };
    std::stringstream modelStream;
    std::string substr;
    modelStream = file->load(modelPath);
    std::getline(modelStream, substr, ','); 
    int numVertices = stoi(substr);
    float* vertices = new float[numVertices*8];
    std::getline(modelStream, substr, '\n');
    int numIndices = stoi(substr);
    int* indices = new int[numIndices];
    int step = 0;
    for (int i = 0; i < numVertices * 8; i++) {
        if(step!=7)
            std::getline(modelStream, substr, ',');
        else
            std::getline(modelStream, substr, '\n');
        vertices[i] = stof(substr);
        if (step == 7)
            step = 0;
        else
            step++;
    }
    step = 0;
    for (int i = 0; i < numIndices; i++) {
        if (step == 2) {
            std::getline(modelStream, substr, '\n');
            step = 0;
        }
        else {
            std::getline(modelStream, substr, ',');
            step++;
        }
        indices[i] = stoi(substr);
    }
    
    conversion->format(vertices, numVertices * 8 * sizeof(float));
    //binds id
    glGenBuffers(1, &VBO);
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &EBO);


    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, numVertices*8*sizeof(float), vertices, GL_STATIC_DRAW);
    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // color attribute
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*4, indices, GL_STATIC_DRAW);
    //texture
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

VertexData::VertexData(const VertexData& data) {
    VAO = data.VAO;
    VBO = data.VBO;
    EBO = data.EBO;
    width = data.width;
    height = data.height;
    trans = data.trans;
}

void VertexData::render() {
    shader->use();
    unsigned int transformLoc = glGetUniformLocation(shader->ID, "location");
    glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));


    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

void VertexData::move(int x, int y) {
    float coor[2] = { float(x),float(y) };
    std::unique_ptr<ConvertToFloat> conversion{ new ConvertToFloat(width,height) };
    conversion->convertToGlobal(coor);
    glm::mat4 temp = glm::mat4(1.0f);
    temp = glm::translate(temp, glm::vec3(coor[0],coor[1], 0.0f));
    trans = temp;
}

void VertexData::rotate(int deg) {

}

void VertexData::destroy() {
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
}

loadFile.h:

#pragma once
#ifndef loadFileH
#define loadFileH

#include <fstream>
#include <sstream>
#include <iostream>

class LoadFile {
    private:
    public:
        LoadFile() {}
        std::stringstream load(const char* path) {
            std::ifstream file;
            std::stringstream stream;
            file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
            try {
                file.open(path);
                stream << file.rdbuf();
                // close file handlers
                file.close();
                return stream;
            }
            catch (std::ifstream::failure e)
            {
                std::cout << "ERROR::FILE_NOT_SUCCESFULLY_READ" << std::endl;
                return stream;
            }
        }
};
#endif

shaderLoader.h:

#ifndef SHADER_H
#define SHADER_H

#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <glad/gl.h> // include glad to get all the required OpenGL headers
#include "loadFile.h"


#include <string>


class Shader
{
public:
    // the program ID
    unsigned int ID;

    // constructor reads and builds the shader
    Shader(const char* vertexPath, const char* fragmentPath) {
        std::unique_ptr<LoadFile> fragFile{ new LoadFile() };
        std::unique_ptr<LoadFile> vertexFile{ new LoadFile() };
        std::string vertexCode;
        std::string fragmentCode;
        vertexCode = vertexFile->load(vertexPath).str();
        fragmentCode = fragFile->load(fragmentPath).str();
        const char* vShaderCode = vertexCode.c_str();
        const char* fShaderCode = fragmentCode.c_str();

        // 2. compile shaders
        unsigned int vertex, fragment;
        int success;
        char infoLog[512];

        // vertex Shader
        vertex = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertex, 1, &vShaderCode, NULL);
        glCompileShader(vertex);
        // print compile errors if any
        glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(vertex, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
        };

        // similiar for Fragment Shader
        fragment = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragment, 1, &fShaderCode, NULL);
        glCompileShader(fragment);
        // print compile errors if any
        glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(fragment, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
        };

        // shader Program
        ID = glCreateProgram();
        glAttachShader(ID, vertex);
        glAttachShader(ID, fragment);
        glLinkProgram(ID);
        // print linking errors if any
        glGetProgramiv(ID, GL_LINK_STATUS, &success);
        if (!success)
        {
            glGetProgramInfoLog(ID, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
        }

        // delete the shaders as they're linked into our program now and no longer necessary
        glDeleteShader(vertex);
        glDeleteShader(fragment);
    }
    // use/activate the shader
    void use(){
        glUseProgram(ID);
    }
};
#endif

The areas that the breakpoint are triggered according to VS are: line 19 of loadFile.h stream << file.rdbuf();, line 27 of shaderLoader.h const char* vShaderCode = vertexCode.c_str();, and line 75 of vertexData.cpp } which is just a closing bracket. If I click continue after the breakpoint, I get the error Unhandled exception at 0x7727FA1D (ntdll.dll) in snek.exe: 0xC0000374: A heap has been corrupted (parameters: 0x772BB960).