lundi 31 juillet 2023

C++ Parameter Pack Sum

I want to calculate sum of any number of arguments given to function sum. Assuming that integers given to the function will satisfy operator+.

If i comment out the function sum() (the one having no arguments), code does not compile. And if i remove the comment block, code does compile and run but never hits the function sum().

I cant seem to understand that why do we need to have sum() function at all as i am using condition on sizeof...(Args)

Will really appreciate if someone can help me understand this?

/*
int sum() {
    std::cout << "Sum with 0 Args" << std::endl;
    return 0; 
}
*/

template <typename T, typename...Args>
T sum(T first, Args...args) {
    // std::cout << sizeof...(Args) << std::endl;
    if(sizeof...(Args) != 0) {
        return first + sum(args...);
    } else {
        std::cout << "Found 0 args" << std::endl;
        return first;
    }
}

int main()
{
    std::cout << sum(1, 2, 3) << std::endl;
    std::cout << sum(1.2, 3.5) << std::endl;
    return 0;
}

Once i uncomment function sum(), i get below output -

Found 0 args 6 Found 0 args 4.7

Basically sum() never get called which is expected but then why do we need it in the first place?

dimanche 30 juillet 2023

Why does following code free memory more than allocated?

Here is my code:

#include <iostream>
using namespace std;

int* NextVal(char str[], int size) {
    int i = 0, j = -1;
    int *nextVal = new int[size];
    nextVal[0] = -1;
    while (i < size) {
        if (j == -1 || str[i] == str[j]) {
            ++j; ++i;
            nextVal[i] = j;
            if (str[i] == str[j]) nextVal[i] = nextVal[j];
        }
        else j = nextVal[j];
    }

    return nextVal;
}

int main() {
    char str[] = { "abaab" };
    char* str0 = new char[100];
    cin >> str0;
    int size = strlen(str);
    int* nextVal = NextVal(str, size);
    delete []nextVal;
    int i = 0, j = 0, size0 = strlen(str0);
    while (i < size0) {
        if (j == -1 || str0[i] == str[j]) {
            ++i; ++j;
        }
        else j = nextVal[j];
    }
    if (i == size0 && j != size) cout << "false";
    else cout << i - size << "\n";
    cout << sizeof(nextVal);
    delete []str0;
    delete nextVal;
}

It is KMP. The last statement report following error: enter image description here

The same error will get if I put the last statement like

int NextVal (){
  while(...){
  ...}
  delete [] nextVal;
  return nextVal;
}

So what is the point? I can free str0 correctly,there is no difference in my opoinion. Why after the while statement nextVal has space more I have allocated?

samedi 29 juillet 2023

why the output is 110 not 111? [duplicate]

#include<iostream>
#include<math.h>
using namespace std;

int main(){
    int i=0, a=0;
    while (i<3)
    {
        a = (pow(10, i)) + a;
        i++;
    }
    
    cout<<a<<endl;
    return 0;
}    

i changed the condition for loop to i<2 and it gives right output that is 11. but than i change the condition to i<3 and it gives 110 not 111. now i changed the value of a to 1 and its gives 111 but if i changed the condititon to i<2 it gives 12.

What am I doing wrong with my code for Mclaurin Series Expansion?

(https://i.stack.imgur.com/3LgGA.png) I have been trying to make a code in c++ for the Mclaurin ’s Series expansion of sin(x), as a review for my Intro to Programming class and my results are always not equivalent to the sample runs. I have been trying to trouble shoot this for hours to no avail. Please help.

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double factorial(int num);
double sum(double number, int n);
int main() {
double number, sin;
int n;
    cout<<"Enter the value of x: ";
    cin>>number;
    cout<<"Enter the number of terms: ";
    cin>>n;
    sin=sum(number,n);
    cout<<"sin("<<number<<") = "<<fixed<<showpoint<<setprecision(6)<<sin<<endl;

    return 0;
}
double factorial(int num){
    double sum=1;
    for(int x=num; x>=1;x--){
        sum*=x;
    }
    return sum;
}
double sum(double number, int n){
    int count=3;
    double term,term1, sum=0, sum2=0, totalSum;

    for(int i=1;i<n-1;i+=2 ){
        term1=(pow(number, count))/ factorial(count);
        sum+=term1;
        count+=4;
        }
    for(int j=0;j<n-2;j+=2){
            term=pow(number, count)/ factorial(count);
            sum2+=term;
            count+=4;
        }
    totalSum=number+sum+sum2;
    return totalSum;
    }

What is key difference between regex_iterator and regex_token_iterator?

Looking at the regex_iterator and regex_token_iterator I see that the key difference is the value_type which is:

  • match_results<BidirIt> for the regex_iterator
  • sub_match<BidirIt> for the regex_token_iterator

At the same time the examples for them (on these pages) show opposite behavior:

  • regex_iterator splits by definition of the token itself in regex
  • regex_token_iterator splits by delimiters description in regex

although, this in not specified in the aforementioned documents.

In the What is the difference between regex_token_iterator and regex_iterator? it is specified that regex_token_iterator could have last parameter -1, 0, or 1 and I can’t find this at the regex_token_iterator. Is this is a kind of common knowledge that I miss or the document misses this?

My specific question is what makes them so different that the code

#include <iostream>
#include <string>
#include <regex>

int main()
{
    std::string input_str = "hi, world";
    const std::regex  reg_ex(R"(\S+\w+|[,.])");

    std::vector<std::string> tokens { 
        std::sregex_token_iterator(input_str.begin(), input_str.end(), reg_ex, 0), 
        std::sregex_token_iterator() 
    };

    for (auto& item : tokens)
    {
        std::cout << item << std::endl;
    }
}

compiles and works without any issues and the same code based on the sregex_iterator doesn’t compile with many error messages which hide the information about the real issue. Actually, it can't make vector<string> from the iterators.

See the demo with the issue.

Is there any way to handle results of the regex_iterator in the same way as results of the sregex_token_iterator and pack them in vector<string> directly as in the example above?

namespace "std" has no member "mutex"

I'm using mingw64 and even a simple program like this failed to compile. Moreover g++ is suggesting a revolutionary solution.

The code-

#include <mutex>

int main()
{
  std::mutex m;
}

The error-

test.cpp: In function 'int main()':
test.cpp:5:8: error: 'mutex' is not a member of 'std'
   std::mutex m;
    ^~~~~

The solution-

test.cpp:5:8: note: 'std::mutex' is defined in header '<mutex>'; did you forget to'#include <mutex>'?
test.cpp:2:1:
+#include <mutex>
 
test.cpp:5:8:
   std::mutex m;
        ^~~~~

How do I compile this?

Why copy constructor is called in capture list of lambda

#include <iostream>
#include <vector>
#include <functional>

using namespace std;

struct B {
    B() {
        std::cout<<"B"<<std::endl;
    }
    
    B(B&& b2) {
        std::cout << "B&& from object moved" << b2.moved_ << std::endl;
        b2.moved_ = true;
    }
    
    B(const B&) {
        std::cout<<"const B&"<<std::endl;
    }
    
    // ~B(){
    //     std::cout<<"~B"<<std::endl;
    // }
    
    int bb=10;
    bool moved_=false;
};

struct FF {
    FF(std::function<void()> ff):ff_(std::move(ff)){}
    std::function<void()> ff_;
};

int main()
{
    std::vector<int> a{1,2,3};
    std::vector<FF> b{};
    B bb;
    std::transform(a.cbegin(), a.cend(), std::back_inserter(b), [x = std::move(bb)](auto const i) {
        
        return FF([xx = std::move(x), i]() {
            std::cout<<"FF"<<i<<std::endl;
        });
    });
    
    for(auto const& j:b) {
      j.ff_();
    }
    return 0;
}

As you can see from the code , my container b is a vector of FF, it accepts a function object as parameter . I want to confirm how lambda capture the parameter.

My question is why const& constructor will be called when xx=std::move(x) in capture list?

I think there should not be extra constructor.

vendredi 28 juillet 2023

why should I use function instead of named lambdas in C++

Recently I've struggled a lot with function deduction and of course lambdas prove to be more flexible here, but doing so I've came to a question, why should I use function instead of named lambdas?

e.g.

namespace
{
auto foo(auto && arg1, auto && arg2){
    return arg1 + arg2;
}

auto bar = [](auto&& arg1, auto && arg2){
    return arg1 + arg2;
}
}

bar is more flexible while doing templates and stuff, but is there any downsides using bar? performance or memory costs in real programming? I've run some tests with assembly output and bar proves to have even less instructions in some cases.

jeudi 27 juillet 2023

Why does std::cout print a string twice depending on scope? [duplicate]

When printing a string without a NULL terminator, C++ outputs the next string twice if the first one is defined outside of main(). This doesn't happen when a NULL terminator is added (next string is printed once in both cases).

#include <iostream>

int main() {
        const char message[4] = {'a', 'b', 'c', 'd'};
        std::cout << message << std::endl;
        std::cout << "Hello" << std::endl;

        return 0;
}

Output:

abcd
Hello
#include <iostream>

const char message[4] = {'a', 'b', 'c', 'd'};
int main() {
        std::cout << message << std::endl;
        std::cout << "Hello" << std::endl;

        return 0;
}

Output:

abcdHello
Hello

How to print the backtrace of all threads?

I am using

void *array[10];
size_t size = backtrace(array, 10);
backtrace_symbols_fd(array, size, STDERR_FILENO);

to print the backtrace for debugging a crash in the field that is difficult to reproduce in the lab. It looks like the crash is not being caused by the thread in the backtrace. Is there a way to print the backtrace of all threads without using core dump and gdb?

Mfence would be inserted by compiler to function using non atomic pointer storing value of atomic pointer

I am reading cppreference of carries_dependency attribute. It seems to me that the following codes snippet from above link is telling that if carries_dependency attribute is not added to print2 function, because of passing the non-atomic pointer int* local which is storing the value of atomic pointer std::atomic<int*> p to print2, compiler would insert a mfence.

I tried to verify above on https://godbolt.org/z/TTE4bM9d6 where has the exact same number of instructions as https://godbolt.org/z/K4Wd4sEG4 that means mfence was not inserted. I can understand because of the x86-64 gcc I used. I tried to verify the same with ARM gcc trunk on https://godbolt.org/z/K6KM4nssK comparing with https://godbolt.org/z/jGYsae7dz. However, I have found got the same conclusion.

So my question is, is my understanding correct that from following snippet cppreference page is telling us mfence should be inserted by compiler if carries_dependency attribute is not added to print2 function? If so, why I can't see get that from above tests on Compiler Explorer? If mfence should be inserted in this case, is it because local is a pointer which compiler takes it as a reference? However, the local pointer and p atomic pointer are pointing at address of x which is not an atomic variable. Why compiler would still insert mfence in this case?

PS I understand I am asking more than 1 question and I am expected to only ask 1 question per post, however, all questions above are closely related to each other. The background information would be redundant if I split each question per post.

#include <atomic>
#include <iostream>
 
void print(int* val)
{
    std::cout << *val << std::endl;
}
 
void print2(int* val [[carries_dependency]])
{
    std::cout << *val << std::endl;
}
 
int main()
{
    int x{42};
    std::atomic<int*> p = &x;
    int* local = p.load(std::memory_order_consume);
 
    if (local)
    {
        // The dependency is explicit, so the compiler knows that local is
        // dereferenced, and that it must ensure that the dependency chain
        // is preserved in order to avoid a fence (on some architectures).
        std::cout << *local << std::endl;
    }
 
    if (local)
    {
        // The definition of print is opaque (assuming it is not inlined),
        // so the compiler must issue a fence in order to ensure that
        // reading *p in print returns the correct value.
        print(local);
    }
 
    if (local)
    {
        // The compiler can assume that although print2 is also opaque then
        // the dependency from the parameter to the dereferenced value is
        // preserved in the instruction stream, and no fence is necessary (on
        // some architectures). Obviously, the definition of print2 must actually
        // preserve this dependency, so the attribute will also impact the
        // generated code for print2.
        print2(local);
    }
}

Hardware ids how to read/write

Hello everyone ive recently started to get in to game hacking and come a cross the name HWID Spoofing while i get waht it does i cant replicate it with my own programm if anyone has knwolage in this field and could share it with me that would be awsome kind regards

I indeed tried to make a hwid spoofer but miserably faild since theres little puplic info

Cannot programmatically remove jpg using ::DeleteFile or "remove"

I cannot delete a jpg using Windows DeleteFile or remove. I can, however, delete other types of files in the same directory (txt, yaml). To make things even weirder, I can open a command prompt and remove the file using the "rm" command (I'm not opening the terminal window as an admin).
I am running Windows 11 and Visual Studio 2019 and yes, I am the owner of and do have full permissions on the file and no, the file is not opened first.

    int retVal = ::remove("C:\\Users\\melis\\Projects\\BartonNoProp.jpg");  //THIS FAILS
    retVal = ::remove("C:\\Users\\melis\\Projects\\Barton.jpg");  //THIS FAILS
    retVal = ::remove("C:\\Users\\melis\\Projects\\ss.yaml");  //THIS IS SUCCESSFUL

    BOOL result = ::MoveFileEx("C:\\Users\\melis\\Projects\\Barton.jpg", "C:\\Users\\melis\\Projects\\Train\\Barton.jpg", MOVEFILE_REPLACE_EXISTING);
    int rr = ::GetLastError();  //THIS SUCCEEDS IF THE SECOND FILE DOESN'T EXIST.  HOWEVER, IT FAILS IF THE SECOND FILE ALREADY EXISTS.

    result = ::DeleteFile("C:\\Users\\melis\\Projects\\ss2.yaml");
    rr = ::GetLastError();  // THIS IS SUCCESSFUL

    result = ::DeleteFile("C:\\Users\\melis\\Projects\\BartonNoProp.jpg");
    rr = ::GetLastError();  // THIS FAILS WITH CODE 5

mercredi 26 juillet 2023

The TCP server send function blocks when the network cable is unplugged?

I encountered a problem: I implemented a TCP socket server. When listening to a client connection, I set a timer (another thread) to send data to the client, but the client does not send data to the server, and all APIs are blocked. When I use a TCP socket client tool to connect to the server, I can normally listen to data from the server. By manually closing the client and reconnecting, I can also listen to data from the server. However, this tool connects to the server and successfully connects and receives data. At this point, I disconnect the network cable and then connect it back. Once the connection is successful, I can no longer receive data, I have checked that my timer thread is working properly. The problem is that the send function in the timer thread is blocked. May I know how to handle this issue? I have set the TCP heartbeat.

mardi 25 juillet 2023

Throwing an Exception from a Signal Handler for Segmentation Fault C++ Linux Debian

I have a requirement to gracefully discard messages if they throw a segmentation fault and continue to listen to the next message in queue. For implementing the same, I have installed a signal handler function for segmentation fault, which throws a runtime exception, and the catch block handles the code for discarding the message.

I have used the compiler flag -fnon-call-exceptions when compiling. I observed that the exception gets caught for some messages but fails sometimes going past the catch block and aborts with the below error.

terminate called after throwing an instance of 'std::runtime_error' what(): Segmentation Fault Aborted (core dumped)

I have also tried adding the jump functions, sigsetjmp and siglongjmp, but it disturbs the flow of code execution and there is an issue when listening to the next message in queue.

I am expecting the code to be able to catch the runtime exception for all messages.

The following is my sample code, which is compiled with the flag -fnon-call-exceptions. It is giving mixed results. Expecting it to work at all times.

#include <iostream>
#include <signal.h>
#include <execinfo.h>
#include <string.h>
//#include <setjmp.h>
 

using namespace std;
void catch_signal(int signalNumber)
{
    throw(10);
}

void testFunc(char* x)
{
    *x = 100;
}
void service_sigset() {
  signal(SIGSEGV, catch_signal);
    try
    {
        testFunc(0);
    }
    catch (int &z)
    {
        cerr << "Caught exception: " << z << endl;
    }
}

int main()
{
    try
    { 
        service_sigset();
    }
    catch(int &z)
    {
        std::cout << "runtime error caught!!!" << std::endl;
    }
    return 0;
}

Can someone please guide me here. Thanks in advance!

lundi 24 juillet 2023

How to solve "Use of auto func(int) before deduction of auto" in C++ [duplicate]

I was trying to use recursion function to calculate factorial of a number. But this time I tried to use the lambda function as a recursive function. The code is below-

#include<iostream>
using namespace std;
auto factorial = [](int n)->int
{
    if(n==0 || n==1)
        return 1;
    else
        return n*factorial(n-1);
};
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin>>n;
    cout<<factorial(n)<<"\n";
    return 0;
}

But the code gives an error which is-

error: use of 'factorial' before deduction of 'auto'

I am not sure what is the meaning of this error and how to solve it. Is it even possible to use lambda function as a recursive function?

I went through these questions here-

But I couldn't figure out how to solve this problem. Can anyone please help with this problem?

samedi 22 juillet 2023

How to check the close-to-verbose status of a thread's "shared state" or "memory state"? How to not make calls to std::async( ) block?

My method that uses multithreading is:

typedef std::pair<std::vector<char>, int> PATH_PAIR;

std::list<PATH_PAIR>
TSP::return_all_paths_list(
    PATH_PAIR                                       parent_path_pair,
    std::list<char>                                 unvisited_cities
) {
    std::list<PATH_PAIR>                            subseq_paths_list;
    std::vector<std::future<std::list<PATH_PAIR>>>  future_vec;
   
    if (unvisited_cities.empty()) { // END RECURSION
        // NON-REALTED CODE
        return subseq_paths_list;
    }

    for (const char curr_city: unvisited_cities) {   // DO RECURSION
        PATH_PAIR                           new_path_pair_addr = parent_path_pair;
        std::list<char>                     subseq_unvisited_cities = unvisited_cities;
        std::future<std::list<PATH_PAIR>>   returned_path_list_future;
        // NON-RELATED CODE
        returned_path_list_future = std::move(std::async(std::launch::async, return_all_paths_list, this, new_path_pair_addr, subseq_unvisited_cities));

        future_vec.push_back(returned_path_list_future);
    }

    while (!future_vec.empty()) {   // GET-VALUES-WHILE
        for (std::future<std::list<PATH_PAIR>>& curr_future : future_vec)  // GET-VALUES-FOR
            if (curr_future.valid()) {
                subseq_paths_list.merge(curr_future.get());
            }
        // future_list.remove_if(
        //     [] (std::future<std::list<PATH_PAIR>> input_future) -> bool {
        //         return !input_future.valid();
        //     }
        // );
    }

    return subseq_paths_list;
}

I have a few questions:

  1. As per cppreference std::async:

    If the std::future obtained from std::async is not moved from or bound to a reference, the destructor of the std::future will block at the end of the full expression until the asynchronous operation completes, essentially making code such as the following synchronous:

    std::async(std::launch::async, []{ f(); }); // temporary's dtor waits for f()
    std::async(std::launch::async, []{ g(); }); // does not start until f() completes
    

    a. What do the words "move from" and "bound to a reference" mean?
    b. Will wrapping the call to std::async inside an std::move make the calls to std::async not block in the suceeding iterations of // DO RECURSION loop?
    c. Or are the calls in the above two lines blocking just because lambdas are used?

  2. How do I check if a shared state is ready?
    a. A call to std::future::wait (and std::future::get) blocks until the shared state is ready. The thing is, I don't want to wait. I want to check if a shared state is ready, if it's not, I want to move on to the next std::future object. How do I do that? std::future::valid only checks if a shared state is associated with an object.
    b. Also, again as per cppreference std::async, the return value of a call to std::async is:

    std::future referring to the shared state created by this call to std::async

    So, in the //GET VALUES loops, the std::future obtained will always return true if std::future::valid is called on it (provided std::future::get isn't called on it yet). If I remove an std::future after an std::future::get is called, I don't have to check the validity of the std::future objects. But, none of the remove element STL methods I've tried don't work, there's compile time errors spanning to about twice the height of my display.

    I thought, maybe calling std::future::get also destroys the object in addition to releasing the shared state, but a small test piece of code I wrote:

    int mul2(int x) {return x << 1; }
    int main() {
        std::vector<std::future<int>> fut_vec;
        for (int i = 0; i < 5; i++) {
            fut_vec.push_back(std::move(std::async(std::launch::async, mul2, i)));
        }
        for (std::vector<std::future<int>>::iterator itr = fut_vec.begin(); itr != fut_vec.end(); itr++) {
            if (itr->valid()) {
                std::cout << "Value: " << itr->get() << " | No. of vec elements(futures): " << fut_vec.size() << std::endl;
            }
        }
    
        return 0;
    }
    

    reveals the fut_vec.size() always returns the same integer.

    How do I destroy an std::future object?

I recently got into multithreading, so now I'm trying to implement the travelling salesman problem using multithreading.

Unable to initialize Gecode's `IntSet` from `Vector`

As per the Gecode documentation "Modelling and Programming with Gecode", an IntVar can be created with IntSet

enter image description here

This is also confirmed by Gecode's reference for IntVar at https://www.gecode.org/doc/6.2.0/reference/classGecode_1_1IntVar.html

enter image description here

And an IntSet can be created using a vector<int> as per https://www.gecode.org/doc/6.2.0/reference/classGecode_1_1IntSet.html

enter image description here

But the following code

std::vector<int> values = {2, 4, 6, 8};
IntVar i;

Class() : i(*this, IntSet(values)) {
}

gives me an error message that looks something like this

In file included from $GECODE_HOME/include/gecode/int.hh:356,
                 from bla.cc:3:
$GECODE_HOME/include/gecode/int/int-set-1.hpp: In instantiation of ‘static void Gecode::IntSetInit<I>::init(Gecode::IntSet&, I&) [with I = std::vector<int>]’:
$GECODE_HOME/include/gecode/int/int-set-1.hpp:87:24:   required from ‘Gecode::IntSet::IntSet(I&) [with I = std::vector<int>]’
bla.cc:14:35:   required from here
$GECODE_HOME/include/gecode/int/int-set-1.hpp:61:15: error: no match for call to ‘(std::vector<int>) ()’
   61 |       while (i()) {
      |              ~^~
$GECODE_HOME/include/gecode/int/int-set-1.hpp:62:22: error: ‘class std::vector<int>’ has no member named ‘min’
   62 |         d[n].min = i.min(); d[n].max = i.max(); size += i.width();
      |                    ~~^~~
$GECODE_HOME/include/gecode/int/int-set-1.hpp:62:42: error: ‘class std::vector<int>’ has no member named ‘max’
   62 |         d[n].min = i.min(); d[n].max = i.max(); size += i.width();
      |                                        ~~^~~
$GECODE_HOME/include/gecode/int/int-set-1.hpp:62:59: error: ‘class std::vector<int>’ has no member named ‘width’
   62 |         d[n].min = i.min(); d[n].max = i.max(); size += i.width();
      |                                                         ~~^~~~~
$GECODE_HOME/include/gecode/int/int-set-1.hpp:63:14: error: no match for ‘operator++’ (operand type is ‘std::vector<int>’)
   63 |         ++n; ++i;
      |              ^~~

Full code

#include <vector>

#include <gecode/int.hh>
#include <gecode/search.hh>
#include <gecode/minimodel.hh>

using namespace Gecode;

class Class : public Space {
public:
  std::vector<int> values = {2, 4, 6, 8};
  IntVar i;

  Class() : i(*this, IntSet(values)) {

  }

  // search support
  Class(Class& s) : Space(s) {
    i.update(*this, s.i);
  }

  virtual Space* copy(void) {
    return new Class(*this);
  }

  // print solution
  void print() {
    std::cout << i << "\n";
  }
};


int main(int argc, char* argv[]) {
    Class* c = new Class;
    DFS<Class> e(c);
    delete c;
    while (Class* s = e.next()) {
      s->print(); delete s;
    }

    return 0;
}

Command to compile

g++ -std=c++20 -O3 -I $GECODE_HOME/include -L$GECODE_HOME/lib -lgecodesearch -lgecodeminimodel -lgecodeint -lgecodekernel -lgecodesupport bla.cc

What am I missing here? Do I misunderstand something?

Returning with a Local Variable in a Function Template

In the example below the function template is returning with a local variable and it works as expected even though the return value is not a reference. Is there a lifetime extension scenario in here? "result" variable is a local one and compiler doesn't generate any messages, and the code works as well. I expect that it fails since a local variable is used in the return statatement but it works.

template <typename F>
auto try(const F& f)
{
    return [f](const std::vector<double>& v)
    {
        std::vector<double> result(v.size());
        std::transform(v.begin(), v.end(), result.begin(), f);
        return result;
    };
}

vendredi 21 juillet 2023

boost signal disconnect problem: slot can still be triggered after slot object has been destroyed

By far I've encountered the same problem. The document in boost web says that the disconnection occurs when 'An object tracked by the slot is destroyed.', however, I tested it doesn't work in that way. So I prefer to disconnect manually although it's little bit troublesome.

My test code :

class MySignal {
public:
    boost::signals2::signal<void ()> signal_one;
    boost::signals2::signal<void ()> signal_two;

};

class MySlot {
public:
    void SlotOne() {
        std::cout << "slot_one" << std::endl;
    }
    void SlotTwo() {
        std::cout << "slot_two" << std::endl;
    }
};

int main() {

    MySignal signal;
    auto* slot = new MySlot;

    auto c = connect(signal.signal_one, slot, &MySlot::SlotOne);
//    c.disconnect();

    if (slot != nullptr) {
        delete slot;
        slot = nullptr;
    }

    signal.signal_one();

    return 0;
}

Can anybody tell me why the slot can still be triggered while I already destroyed the slot object?

I can only convince myself that the boost's document says the 'disconnection' can occur under some circumstances but doesn't say it will happen automatically.

Words below are what the boost document says:
Signal/slot disconnections occur when any of these conditions occur:
1.The connection is explicitly disconnected via the connection's disconnect method directly, or indirectly via the signal's disconnect method, or scoped_connection's destructor.
2.An object tracked by the slot is destroyed.
3.The signal is destroyed.

Generation a pointer-to-member function or a member matching another declaration

This particular method was used in code to bridge a generic algorithm and some generated class implementations (represented here by class B):

// A class generated by outside source
struct B {
    void foo(int);
    void foo();

    int bar();
    int bar() const;

    float blah(int) const;
};

#define DECLARE_METHOD_TYPE(TName, CName, Func)    \
     template<typename ...Args>                    \
     using TName = decltype(                       \
     std::declval<CName>().Func(std::declval<Args>() ...)) \
         (CName::*) (Args...)

#define METHOD_PTR(TName, ... ) static constexpr TName<__VA_ARGS__>

// A bridge
struct A 
{
    DECLARE_METHOD_TYPE(FooPtr, B, foo);

    // need both declaration
    DECLARE_METHOD_TYPE(BarPtr, B, bar);
    DECLARE_METHOD_TYPE(BarPtrConst, B, bar) const;

    // must be const
    DECLARE_METHOD_TYPE(BlahPtrConst, B, blah) const;

    METHOD_PTR(FooPtr, int) b_foo_n = &B::foo;
    METHOD_PTR(FooPtr)      b_foo   = &B::foo;

    METHOD_PTR(BarPtr)      b_bar   = &B::bar;
    METHOD_PTR(BarPtrConst) b_cbar  = &B::bar;

    // must be exact
    METHOD_PTR(BlahPtrConst, int) b_blah = &B::blah;
};

Is there w way to declare each pointer in a single statement? main proble there is that the pointer type is a template and I need a unique typename for it.

Or is there a way to create a macro that generates member function which would call B's member (like a visitor). I think, I can declare such function, but I cannot define it.

jeudi 20 juillet 2023

A question about type traits std::remove_cv

My reference is to the example provided hereunder:

std::remove_cv, std::remove_const, std::remove_volatile

In the example,

using type4 = std::remove_cv<const volatile int*>::type;
using type5 = std::remove_cv<int* const volatile>::type;

std::cout << std::is_same<type4, int*>::value << ' '
              << std::is_same<type4, const volatile int*>::value << '\n';

    std::cout << std::is_same<type5, int*>::value << '\n';

Output

false true

true

I am assuming that there is a typo in the output as it doesn't match the test in the example, if my understanding of the concept is correct. The output instead should have been

true false

true

Can someone confirm or correct this?

TIA

c++ coroutine runs avx SIMD code, but causes SIGSEGV

c++ coroutine runs avx SIMD code, but causes SIGSEGV for AVX and AVX512


HelloCoroutine hello(int& index, int id, int group_size) {
#if 1
    __mmask8 res=0;
    for(auto i= index++; i< 20; i=index++)
    {

#if 0
// error
        std::cout <<"step 1" <<std::endl;
        __m512i v_offset = _mm512_set1_epi64(int64_t (i));
        std::cout <<"step 2" <<std::endl;
        __m512i v_size = _mm512_set1_epi64(int64_t(group_size));
        std::cout <<"step 3" <<std::endl;
        res = _mm512_cmpgt_epi64_mask(v_offset, v_size);
#elif 1 
// error
        std::cout <<"step 1" <<std::endl;
        __m256i v_offset = _mm256_set1_epi32(int32_t (i));
        std::cout <<"step 2" <<std::endl;
        __m256i v_size = _mm256_set1_epi32(int32_t(group_size));
        std::cout <<"step 3" <<std::endl;
        res = _mm256_cmpgt_epi32_mask(v_offset, v_size);

#else
// OK
        std::cout <<"step 1" <<std::endl;
        __m128i v_offset = _mm_set1_epi32(int32_t (i));
        std::cout <<"step 2" <<std::endl;
        __m128i v_size = _mm_set1_epi32(int32_t(group_size));
        std::cout <<"step 3" <<std::endl;
        res = _mm_cmpgt_epi32_mask(v_offset, v_size);
#endif       
#else
    int res=0;
    for(auto i= index++; i< 20; i=index++)
    {
        res = i > group_size;
#endif
        cout <<i << " > " << group_size <<" ? " << (int)res<<endl;
        co_await std::suspend_always();
    }
}

compile at https://godbolt.org/z/hcP988z8b

-std=c++20 -fcoroutines -mbmi2 -mavx -mavx512f -mavx512pf -mavx512er -mavx512cd -mavx512vl

but result error for avx and avx512, only SSE works OK

Program returned: 139 Program terminated with signal: SIGSEGV step 1

mercredi 19 juillet 2023

template parameter type deduction misunderstanding

I have a template function with a universal (forwarding) parameter, as shown below:

#include <iostream>
#include <type_traits>

template <typename T>
void foo(T&& arg)
{
    // Check the type of T
    if constexpr (std::is_lvalue_reference_v<T>) {
        std::cout << "T is an lvalue reference" << std::endl;
    } else if constexpr (std::is_rvalue_reference_v<T>) {
        std::cout << "T is an rvalue reference" << std::endl;
    } else {
        std::cout << "T is neither lvalue nor rvalue reference" << std::endl;
    }
}

int main() 
{
    foo(10);
    return 0;
}

In this code, I have a function template foo with a universal (forwarding) reference parameter named arg. The purpose of this function is to check the type of the template parameter T.

In the main function, I call foo with the argument 10. Since 10 is an rvalue, I expect the result to be 'T is an rvalue reference.' However, when I compile and run this code in the "https://ift.tt/K2dR0I5" online compiler using the "g++ -std=c++17 -Wall -pthread -fno-elide-constructors -Qn main.cpp && ./a.out" flags, the actual output is 'T is neither lvalue nor rvalue reference.'

My assumption is that the template type T would be deduced as int&& here. But I guess the result is int which is similar to the behavior of decltype(10). Is the type deduction here the same as calling decltype(X)? Or is there any rule here?

moreover:

if call foo as below,

int x = 10;
foo(std::move(x));

the result is "T is neither lvalue nor rvalue reference" ? I expect "T is an rvalue reference"...

mardi 18 juillet 2023

Can't reproduce normally distributed random numbers in parallel

I want to generate a reproducible sequence of random numbers in parallel with OpenMP. I wrote a small code that creates for each thread its own RNG with different seed. But when I start generating random numbers in parallel, something strange happens. With uniform distribution I get reproducible results (rand() here to generate same sequence of seeds whenever i launch the program), but with normal distribution i get different results!

More specifically, every time I run the program, the array seems to be shuffled.

My question: Why this might be happening? And how do I resolve this issue?

#include <iostream>
#include <random>
#include <omp.h>

int main() {
    std::normal_distribution<> normal(0,1);
    std::uniform_real_distribution<> uniform(0,1);
    std::mt19937 *rng = new std::mt19937[omp_get_max_threads()];
    for(int i = 0; i < omp_get_max_threads(); ++i) {
        rng[i].seed(1+i);
    }

    int N = 100;
    double* arr = new double[N];
#pragma omp parallel for
    for(int i = 0; i < N; ++i) {
        arr[i] = normal(rng[omp_get_thread_num()]);
    }
    for(int i = 0; i < N; ++i) {
        std::cout << arr[i] << std::endl;
    }

    delete[] arr;
    delete[] rng;
    return 0;
}

lundi 17 juillet 2023

What difference between "a reference to an rvalue" and "a const variable"?

What difference between "a reference to an rvalue" and "a const variable"?

  • a reference to an rvalue=can NOT use as a variable? so can NOT change its value?

  • a const variable=can NOT change its value?

Perhaps they're equivalent in use?

Can function templates slow compilation

I have a class with a function template.

class Foo {
 public:
  void Foo_fn1();

  template <typename Closure>
  void Foo_util (Closure&& closure) {
    Foo_fn1();
    std::forward<Closure>(closure());
  }

};

The above is part of a .h file that has been included at least 10k times in the code base. My question is the following:

Can such usage of templates slow down compilation? Would it be better to write it in a util class with the following signature:

  template <typename Closure>
  void Foo_util (Foo foo, Closure&& closure) {
    foo.Foo_fn1();
    std::forward<Closure>(closure());
  }

Why or Why not? Any documentation explaining the above would be helpful.

Loop over all months in chrono

I need iterate all months in a code:

for (auto m = std::chrono::January; m <= std::chrono::December; m++)
  std::cout << std::format(std::locale { "pt_BR.UTF-8" }, "{:L%B}\n", m);

But it happens it's a infinity loop, because the std::chrono::month increment has a modulo 12 + 1 behavior. So when the loop m variable reaches December (12), it wraps around to January (1).

I tried with std::views::iota:

for (auto m : std::views::iota(std::chrono::January) | std::views::take(12))
  std::cout << std::format(std::locale { "pt_BR.UTF-8" }, "{:L%B}\n", m);

But fails to compile as std::chrono::month don't satisfies the concept std::weakly_incrementable.

dimanche 16 juillet 2023

std::__1::ostream cannot be defined in the current scope

I have no idea why it is telling me it is out of scope.

namespace sdds
{
    class Shape
    {
    public:

        virtual ~Shape() {} // Empty virtual destructor

        virtual void draw(std::ostream &os)const = 0; //Returns void and receives a reference to ostream as an argument
        virtual void getSpecs(std::istream &is) = 0; //Returns void and receives a reference to istream as an argument.
    }

    //Helper Functions:
    std::ostream& operator<<(std::ostream &os, const Shape& shape); //Overload the insertion so any shape object can be written
    std::istream& operator>>(std::istream &is, Shape& shape); //Overload the extraction operators so any shape object can be read 

my error:

type "std::__1::ostream" cannot be defined in the current scopeC/C++(551)

I have not made my .cpp file for this class yet.

How to share memory between C++ and python code through pybind?

I want to parquet serialize a Pandas data frame in Python into BytesIO buffer and then invoke C++ call through pybind which would deserialize it into arrow table from the in-memory buffer. I am able to serialize the dataframe into python bytes using io.BytesIO , but can't find a good way to send its underlying address to C++. Since they share address space I suppose this should be very much possible.

Thanks

How to initialize multi vector in c++14

In c++11 we can initialize multidimensional vector as: enter image description here

How can I do the same in c++ 14 .

I used to make it run by using c++11 but I need to use c++ 14. Could not find post related to it , if anyone of you find it please share link

How for loop with &&(and) condition works

On LeetCode a user posted his solution, but this line of code was pretty unclear to me, I tried to debug but could not understand it's working here is the piece of code.

string p = "c*a*b";
vector<int>dp(p.size()+1, 0);
for (int j = 0; j < p.size() && p[j] == '*'; ++j) {
         dp[j + 1] = 1;
     }

The output comes as [0 0 0 0 0 0 ]

whereas I guess the output should be

at j = 1, p[j] ==, so dp[1+1] =1
at j = 3, p[j] ==
, so dp[3+1] =1

and finally it should be [0 0 1 0 1 0 ]

Can someone explain me the working for the above for loop

samedi 15 juillet 2023

Difference Between Two Strings question in c++

Diff Between Two Strings Given two strings of uppercase letters source and target, list (in string form) a sequence of edits to convert from source to target that uses the least edits possible.

For example, with strings source = "ABCDEFG", and target = "ABDFFGH" we might return: ["A", "B", "-C", "D", "-E", "F", "+F", "G", "+H"

More formally, for each character C in source, we will either write the token C, which does not count as an edit; or write the token -C, which counts as an edit.

Additionally, between any token that we write, we may write +D where D is any letter, which counts as an edit.

At the end, when reading the tokens from left to right, and not including tokens prefixed with a minus-sign, the letters should spell out target (when ignoring plus-signs.)

In the example, the answer of A B -C D -E F +F G +H has total number of edits 4 (the minimum possible), and ignoring subtraction-tokens, spells out A, B, D, F, +F, G, +H which represents the string target.

If there are multiple answers, use the answer that favors removing from the source first.

I have written the following code

#include <iostream>
#include <string>
 #include <vector>

using namespace std;

int myfunc(const string& source,const string& target,int i,int j,vector<vector<int>>& dp){
  if(i==source.size() || j==target.size()) return target.size()-j;
  if(dp[i][j]!=-1) return dp[i][j];
  if(source[i]==target[j]) return dp[i][j]=myfunc(source,target,i+1,j+1,dp);
   return dp[i][j]=1+min(myfunc(source,target,i+1,j,dp),myfunc(source,target,i,j+1,dp));
}
vector<string> diffBetweenTwoStrings(const string& source,const string& target)
{
    // your code goes here
  int m=source.size();
  int n=target.size();
  vector<vector<int>> dp(m+1,vector<int>(n+1,-1));
  int x=myfunc(source,target,0,0,dp);
  
  vector<string> result;
  int i=0;
  int j=0;
  while(i<m && j<n){
    if(source[i]==target[j]){
      string storer="";
      storer+=source[i];
      result.push_back(storer);
      i++;
      j++;
    }
    else{
      if(dp[i+1][j]<=dp[i][j+1]){
      string storer="";
      storer+=source[i];
        result.push_back("-"+storer);
        i++;
      }
      else{
              string storer="";
      storer+=target[j];
        result.push_back("+"+storer);
        j++;
      }
    }
  }
  
  while(j<n){
      string storer="";
      storer+=target[j];
    result.push_back("+"+storer);
    j++;
  }
  return result;
}

I know that I have to use dynamic programming followed by construction of the vector but I it is giving me incorrect result.this is the output I am getting Minimum edits: 10 Sequence of edits: A B -C D -E F -G +F +G +H but I need "A", "B", "-C", "D", "-E", "F", "+F", "G", "+H" I don't know where have I gone wrong?

vendredi 14 juillet 2023

How to create an already-resolved future

I have a function that returns a std::future. I have added a cache to the implementation, and I would like to optionally return a value immediately if it does not need to be recalculated.

How can I create an already-resolved future?

// Class declarations shortened to minimal example to communicate intent
class MyClass {
    Cache m_cache;

    std::future<int> foo(int arg);
}

class Cache {
    std::optional<int> get(int arg);
}

std::future<int> MyClass::foo(int arg) {
    if (auto res = m_cache.get(arg)) {
        // *res is my result
        return std::future(*res); // ????? Doesn't work
    }
    // If the cache misses, we need to calculate it
    // Fire up the ol' thread pool and get to work
    return std::launch(std::launch::async /* ommited for brevity */);
}

I'm targeting C++20.

std::function does not match lambda as parameter in fold-expression template function

in c++ 11 I declared 2 functions in the same namespace (class Database):

template <typename... Ts> bool HandleStmt(sqlite3_stmt *pSQL, std::function<void(std::tuple<Ts...>)> f)
bool Database::WALModeEnabled()

I get this error when compiling:

source/Database.cpp: In member function 'bool Database::WALModeEnabled()':
source/Database.cpp:180:30: error: no matching function for call to 
'Database::HandleStmt(sqlite3_stmt*&, Database::WALModeEnabled()::<lambda(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >)>&)'
  180 |         HandleStmt(pSQL, func);
      |                              ^
In file included from source/Database.cpp:6:
source/include/Database.h:151:36: note: candidate: 'template<class ... Ts> bool Database::HandleStmt(sqlite3_stmt*, std::function<void(std::tuple<_Tps ...>)>)'
  151 |     template <typename... Ts> bool HandleStmt(sqlite3_stmt *pSQL, std::function<void(std::tuple<Ts...>)> f)
      |                                    ^~~~~~~~~~
source/include/Database.h:151:36: note:   template argument deduction/substitution failed:
source/Database.cpp:180:30: note:   'Database::WALModeEnabled()::<lambda(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >)>' is not derived from 'std::function<void(std::tuple<_Tps ...>)>'
  180 |         HandleStmt(pSQL, func);
      |                              ^

WALModeEnabled prepares an SQL statement and calls the HandleStmt with the stmt pointer and a lambda containing some code that is executed when the SQL stmt is done/found, implemented in Database.cpp:

bool Database::WALModeEnabled()
{
    sqlite3_stmt *pSQL = nullptr;
    bool WALMode = false;
    if (PrepareStmt(&pSQL, "PRAGMA journal_mode")) {
        auto func = [&WALMode](std::tuple<std::string> wal_from_db) {
            WALMode = (std::get<0>(wal_from_db) == "WAL");
        };
        HandleStmt(pSQL, func);
    }

    CleanStmt(pSQL);
    return WALMode;
}

HandleStmt wraps sql stmt with SQLITE_BUSY handling in a generic function: This function is implemented where it is declared in the Database class, Database.h.

template <typename... Ts> bool HandleStmt(sqlite3_stmt *pSQL, std::function<void(std::tuple<Ts...>)> f)
{
    bool hasData = true;
    while (hasData) {
        switch (sqlite3_step(pSQL)) {
            case SQLITE_ROW:
                f(selectstmt::make_result<Ts...>(pSQL));
                break;
            case SQLITE_BUSY:
                sqlite3_sleep(SQL_BUSY_TIMEOUT_MS);
                break;
            case SQLITE_DONE:
            case SQLITE_OK:
                hasData = false;
                break;
            default:
                LogError();
                return false;
        }
    }
    return true;
}

The selectstmt::make_result<Ts...>(pSQL) call calls the sqlite3_column_... functions for any number of types, this works and is used in other parts of the code base.


I have tried some thing, all resulting in the code you see above, unable to defeat the error.

Compiler explorer is able to compile it without issue on mvsc x86; but not on clang x86-64 (same error).

Passing a simple test function void test(std::tuple<std::string> wal_from_db) with empty body also results in the same error.

I expect the HandleStmt to be called with a lambda with any number and types of parameters.

C++ Lambdas in return statements

Trying out C++ Lambdas. Since lambdas are expressions, they should work with return statements. But obv I was wrong.

My code is:

std::list<char>                                     all_cities;
std::list<std::pair<std::vector<char>, int>>        all_paths_list;

//stuff that doesn't matter

int size = all_cities.size();
all_paths_list.resize( return ( [&size] () -> int {
    size--;
    int fact = 1;
    while (x || 0)
        fact *= x--;

    return fact;
}));

Why isn't this working? Do lambdas HAVE to be given as args to functions that take a functor/lambda? Are there ways to make this work?

Keep in mind that all my code is inside a class, the code above (starting from line 6) is in the constructor.

jeudi 13 juillet 2023

C++ 11 function composition with helper struct performance overhead

As we know, in C++ 11, can't deduce the return type of function returning lambda with auto or decltype(auto). So can't use code like below.

template <typename F, typename G>
constexpr decltype(auto) compose(const F& f, const G& g) noexcept {
    return [&f,&g](auto&& x){
        return f(g(std::forward<decltype(x)>(x)));
    };
}

Instead, work around like below could be employed;

template <typename F, typename G>
struct Composed
{
    const F &f;
    const G &g;

    Composed(const F &f, const G &g) : f(f), g(g) {}

    template <typename Arg>

    inline auto operator()(Arg &&arg) -> decltype(f(g(std::forward<Arg>(arg))))
    {
        return f(g(std::forward<Arg>(arg)));
    }
};

template <typename F, typename G>
Composed<F, G> compose(const F &f, const G &g)
{
    return Composed<F, G>(f, g);
}

As alway, the actuall performance could be vary by time, but what would be the general performance of this approach compared to lambda capturing lambda? Does adding inline in front of operator() could help? Or still there is inevitable overhead?

Using std::vector's emplace with const reference member

I was using emplace_back on a vector of my class A that has a const reference member variable of class Handle with some success. However I needed to change it to use emplace instead to be able to insert at certain index. But that doesn't seem to compile. Looking at cppreference, I can't tell what the difference between the two methods is, except that one takes an explicit iterator

#include <vector>

class Handle
{
    int do_something();
};

class A
{
public:
    A(int a, float d, const Handle& h) : a_(a), d_(d), h_(h) {}
private:
    int a_;
    float d_;
    const Handle& h_;
};

int main()
{
    Handle h;
    std::vector<A> foo;
    foo.reserve(10);
    foo.emplace_back(3, 4.5, h); // OK
    // foo.emplace(foo.begin() + 3, 3, 4.5, h); // NOT OK
}

I get an error on using emplace :

In file included from main.cpp:7:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/vector:1759:18: error: object of type 'A' cannot be assigned because its copy assignment operator is implicitly deleted
            *__p = _VSTD::move(__tmp.get());
                 ^
main.cpp:41:6: note: in instantiation of function template specialization 'std::vector<A>::emplace<int, double, Handle &>' requested here
        foo.emplace(foo.begin() + 3, 3, 4.5, h);
            ^
main.cpp:22:16: note: copy assignment operator of 'A' is implicitly deleted because field 'h_' is of reference type 'const Handle &'
        const Handle& h_;

Do I need to change my class design to accommodate using emplace?

I found this question but it doesn't seem to provide an alternative

C++ template specialization depending of Enum value [closed]

I have a class with a templated method taking several type of data. Depending of enum value, this class call several listeners. Currently I shall propagate the types into the listeners even if they does not use the data.

In each listener I want to have only methods for the data it needs.

I want to specialize template depending of an enum value: Something like this:

struct FooA{};
struct FooB{};

enum class Listener_T : int8_t
{
   E_1,
   E_2
};

struct ListenerA
{
   void doSpecificToA(FooA value){};
};

struct ListenerB
{
   void doSpecificToB(FooB value){};
};

struct Generic
{
   ListenerA lstA;
   ListenerB lstB;

   template <typename Data, Listener_T Enum>
   typename std::enable_if<(Enum == Listener_T::E_1) && (std::is_same<Data, FooA>::value), void>::type doSomething(Data data, Listener_T enumLst)
   {
      lstA.doSpecificToA(data);
   };

   template <typename Data, Listener_T Enum>
   typename std::enable_if<(Enum == Listener_T::E_2) && (std::is_same<Data, FooB>::value), void>::type doSomething(Data data, Listener_T enumLst)
   {
      lstB.doSpecificToB(data);
   };



   template<typename Data>
   void doOnData(Data data, Listener_T enumLst)
   {
      doSomething(data, enumLst);
   }
};


int main()
{
FooA a;
FooA b;
Generic g;

g.doOnData(a, Listener_T::E_1);
g.doOnData(b, Listener_T::E_2);


}

thanks

How does timer interrupts work on TI AM64x

I never used timers for embedded micro controller programming, so there are several things I would like to learn about. I am using the TI AM64x chip and try to understand the example in the AM64x Timer SDK Guide:

TimerP_Params timerParams;
/* setup timer but dont start it */
TimerP_Params_init(&timerParams);
timerParams.inputPreScaler    = 1u;
timerParams.inputClkHz        = 250u*1000u*1000u;
timerParams.periodInUsec      = 10u*1000u;
timerParams.oneshotMode       = 0;
timerParams.enableOverflowInt = 1;
TimerP_setup(timerBaseAddr, &timerParams);

To my understanding the timer can trigger 3 different interrupts (overflow, match, compare). But exactly when and how are these interrupts triggered?

Overflow

  1. Is this triggered after periodInUsec or once the 32bit counter is overflown? I need to trigger an interrupt after a certain time.
  2. If enableOverflowInt is enabled, is the interrupt automatically triggered? How do I capture the interrupt in my code? Or do I need to deal with it manually, like this:
while(true) {
  if(TimerP_isOverflowed(timerBaseAddr)) {
    // do stuff...
  }
  TimerP_clearOverflowInt(timerBaseAddr)
}

Match, Compare

How do I "activate" these interrupts? The timer parameters seem to have no settings for these triggers (like enableOverflowInt). However there is this function TimerP_getCount(timerBaseAddr), but it will return the 32bit counter value. So I need to convert the time value and compare it to the counter value? And I have to do it manually again?

Further information: AM64x User Guide (Chapter 12.5.3 Timers; page 8061).
Thanks a lot for your help!

mercredi 12 juillet 2023

In C++ 11 Is there any way to branch by if a function parameter is compile-time constant or not?

Is there anyway I can tell function argument is compile time-constant or not in C++ 11?. I would like to branch the functions body based on the results. For example, like below;

template <T>
size_t get_length(const T &t)
{
    return t.size();
}

template <typename T, size_t N>
size_t get_length(const std::array<T, N> &t)
{
    return N;
}

// Maybe some template
??? foo(size_t length)
{
    ...
    // If length could be evaluated at compile time,
    return std::array<int, length>{};

    ...
    // Otherwise,
    return std::vector<int>(length);
}


// ??? and auto should be std::array if bar is std::array, std::vector if bar is std::vector or etc.
auto x = foo(get_length(bar));

I believe this need two task; First it should be able to determine if a value is compile time evaluable or not. Second, convert a value to compile time constant if possible.

Is there anyway one can do this? Or is there any reason this is impossible? It seems some say to use template function, but that forces caller to put compile time constant and not what I am looking for.

Is there any way to prevent calling a specific function in certain part of code in C++

I'm currently working on implementing a module, which consist of three functions including Init(), Process() and Release(). And I'd like to find a way to throw compile error if using std::vector::push_back in Process() and Release() functions. Is there any possible way? Thank all!

class AModule {
 private:
  std::vector<std::int32_t> vector_list;

 public:
  bool Init() override {
    vector_list.push_back(10); // Allow to use push_back function only in Init state
  }
  void Process() override {
    vector_list.push_back(10); // Should throw compile error here
  }
  void Release() override {
    vector_list.push_back(10); // Should throw compile error here
  }
};

I have try using static_assert by wrapping the vector class, but it doesnt work properly.

mardi 11 juillet 2023

What if cv.notify_one() is called before cv.wait?

Question solved(realized my mistake).
- I'll leave this question undeleted for future learners, but let me know if it's inappropriate.


This is an example code for std::condition_variable in cppreference.com:

#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
 
std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
 
void worker_thread()
{
    // Wait until main() sends data
    std::unique_lock lk(m);
    cv.wait(lk, []{return ready;});
 
    // after the wait, we own the lock.
    std::cout << "Worker thread is processing data\n";
    data += " after processing";
 
    // Send data back to main()
    processed = true;
    std::cout << "Worker thread signals data processing completed\n";
 
    // Manual unlocking is done before notifying, to avoid waking up
    // the waiting thread only to block again (see notify_one for details)
    lk.unlock();
    cv.notify_one();
}
 
int main()
{
    std::thread worker(worker_thread);
 
    data = "Example data";
    // send data to the worker thread
    {
        std::lock_guard lk(m);
        ready = true;
        std::cout << "main() signals data ready for processing\n";
    } 
    cv.notify_one(); // <-What if the main thread executes until here, before the worker thread wait?
 
    // wait for the worker
    {
        std::unique_lock lk(m); // <-Edit: what if main thread lock first?
        cv.wait(lk, []{return processed;});
    }
    std::cout << "Back in main(), data = " << data << '\n';
 
    worker.join();
}

As I commented in the above code, let's say the main thread executes the cv.notify_one() before the worker thread does cv.wait(lk, []{return ready;}). Isn't this a deadlock?

std::condition_variable::notify_one page of cppreference.com also seems to mention this situation:

This makes it impossible for notify_one() to, for example, be delayed and unblock a thread that started waiting just after the call to notify_one() was made.

How does the above code not have any problem(deadlock)?

Edit: I think the wait overload is equivalent to while (!ready) {wait(lk);} so it would be ok, but still, what if the main thread acquires the std::unique_lock lk(m); first?

Edit2: (Question resolved) Sorry, my mistake. since the wait overload is equivalent to while (!ready) {wait(lk);} so it would be ok, and even if the main thread acquires the std::unique_lock lk(m); first, no problem because lk would be unlocked when the main thread executes cv.wait(lk, []{return processed;});.

Operator overloading inside struct

Why i need to make friend keyword if every member of strct is public.

Example:

struct Vector{ int x, y;

friend std::ostream &operator<<(std::ostream &COUT, const Vector &v){
    std::cout << "x: " << v.x << " y: " << v.y;
    return COUT;
}

};

Why can't it be like this:

struct Vector{ int x, y;

std::ostream &operator<<(std::ostream &COUT, const Vector &v){
        std::cout << "x: " << v.x << " y: " << v.y;
    return COUT;
}

};

Invalid attribute value in C High Level Synthesis on Vivado 2018.2 CMD

I am working with xfOpenCV and Vivado High Level Synthesis (implementing a machine learning accelerator) and I have written the main module and its test bench.

The TCL script that I am trying to run is as follows:

open_project FSRCNN
set_top FSRCNN
add_files FSRCNN.cpp -cflags "-D__XFCV_HLS_MODE__ --std=c++11 -IC:\xfopencv-2018.2\include"
add_files -tb tb.cpp -cflags "-IC:\xfopencv-2018.2\include -IC:\opencv\install\include -D__XFCV_HLS_MODE__ --std=c++11 -Wno-unknown-pragmas"
add_files -tb input_image.jpeg -cflags "-Wno-unknown-pragmas"
open_solution "solution1"
set_part {xc7z020clg400-1} -tool vivado
create_clock -period 4 -name default
csim_design -ldflags {-L C:\opencv\install\x64\mingw\lib -lopencv_core453 -lopencv_highgui453 -lopencv_imgproc453 -lopencv_imgcodecs453 -lopencv_flann453 -lopencv_features2d453} -argv {input_image.jpeg} -clean 
csynth_design
export_design -format ip_catalog

When I run it through Vivado Command Prompt by the following command,

`C:\Users\Administrator\Desktop\vhc>vivado_hls -f run_hls.tcl` 

I get the following error:

`INFO: [HLS 200-10] In directory 'C:/Users/Administrator/Desktop/vhc'
INFO: [HLS 200-10] Creating and opening project 'C:/Users/Administrator/Desktop/
vhc/FSRCNN'.
INFO: [HLS 200-10] Adding design file 'FSRCNN.cpp' to the project
Invalid attribute value '-D__XFCV_HLS_MODE__ --std=c++11 -IC:opencv-2018.2includ
e'
    while executing
"source [lindex $::argv 1] "
    ("uplevel" body line 1)
    invoked from within
"uplevel \#0 { source [lindex $::argv 1] } "

INFO: [Common 17-206] Exiting vivado_hls at Tue Jul 11 12:35:42 2023...`

I have checked whether my G++ compiler supports std c++11 and it does. The paths I have added to xfOpenCV, OpenCV for module and testbench file are also correct.

I am not sure how to proceed with this problem. Help will be appreciated.

lundi 10 juillet 2023

Thread Safe Singleton in C11

I am aware that C++11 insure that a static variable inside a block scope is thread safe and is always created once only. Using this mysingelton looks something like below.

class singleton
{
    singleton(){}
    singleton(const singleton& s)=delete;
    singleton& operator=(const singleton& s)=delete;

    singleton(singleton&& s)=delete;
    singleton& operator=( singleton&& s)=delete;
    
    public:
     static singleton* GetInstance();
     static std::shared_ptr<singleton> GetInstanceSP();
          
};

singleton* singleton::GetInstance()
{
        static singleton sObject;
        return &sObject;
}

But this will have an issue, sObject will obviously be destructed before the Object which is using it if the caller is static or global. So I tried below solution which looks and working good

std::shared_ptr<singleton> singleton::GetInstanceSP()
{
        static std::shared_ptr<singleton> sp(new singleton);
        return sp;
}

Is this solution OK? or still it has some loopholes. I didn't go for unique_ptr for same reason as its destructor will be called before its client.

Also one more query: Will below code is also thread safe? if so why this is not in any book or refrence example

static singelton *sp(new singelton);
reurn sp;

W

Doesn't multiple std::lock_guard guarantee the order of locks?

In the cppreference.com std::lock example, there is a code like this:

    // use std::lock to acquire two locks without worrying about 
    // other calls to assign_lunch_partner deadlocking us
    {
        std::lock(e1.m, e2.m);
        std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock);
        std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock);    
  1. I thought the consistent ordering (lock lk1 first, and then lock lk2) across the different threads is enough to avoid deadlock, but why do we need std::lock(e1.m, e2.m)?
    (I also read other questions such as this but still not sure why just locking with multiple std::lock_guards are not enough even though they're locking in the same order.)

  2. Is this related to the fact that std::lock_guard supports RAII style?

dimanche 9 juillet 2023

Can anonymous union be simply const (not constexpr)?

In the following example, an anonymous union declares member int i, which is injected in the enclosing scope, and const precedes the union declaration:

int main() {
    const union {
        int i = 0;
    };
    i = 1;
}

The compilers diverge in handling of this program.

MSVC accepts union declaration, but rejects i = 1 with the error:

error C3892: '$S1': you cannot assign to a variable that is const

GCC accepts the whole program without any warning, simply ignoring the const prefix.

Clang in -pedantic-errors mode issues the error:

anonymous union cannot be 'const' [-Werror,-Wpedantic]

Online demo

Which compiler is correct here?

Extract Eigen subarray based on a boolean array

I have two Eigen::VectorXd named xl and xu with the same size. Based on these arrays, I build a boolean array fixed_indices as follows (Given some tolerance tol).

Eigen::Vector<bool, Eigen::Dynamic> fixed_indices = (xl - xu).array().abs() <= tol;

I want to extract the values of xl and xu where fixed_indices is true. In other words, in the Python world (using NumPy), I would do

fixed_values = 0.5 * (xl[fixed_indices] + xu[fixed_indices])

How can I do that with Eigen arrays? Thank you very much for the help!

samedi 8 juillet 2023

Can't find initializer_list lib when compiling with Green hills compiler

I am using Green Hills compiler version "2015.1.7" and it gives me this error

E:\Repos\somepath\json.hpp", line 40: fatal error #5: could not open source file "initializer_list" #include <initializer_list> // initializer_list ^

i made sure to enable --std=c++11 in my cmakelists but still same issue ... when i searched in greenhills folder for initializer_list i didn't find it so it makes sense but is my compiler corrupted and missing files or greenhills doesn't support c++ std libraries ?

vendredi 7 juillet 2023

Is there a function to call the class name in a template<> without typing the name of the class yourself?

I am trying to get the type name of a class. Of course, I could just use typename(class) but I need to place it in a template like this

ClassA<typeid(class).name()> a = ClassA<typeid(class).name()>(args);

This is what I tried:

template<class T>
class A
{
public:
   T t; // the class

   A(T t1)
   {
      t = t1;
   }
};

class B // example class
{
public:
   int i;

   B(int i1)
   {
      i = i1;
   }
};

int main()
{
   B b = B(1);
   A<typeid(b).name()>(b) a = A<typeid(b).name()>(b); // my issue
}

But it always gives me an error.

'A': invalid template argument for 'T', type expected.

Is there any way round this (class A needs to be able to accept any class in one attribute)?

jeudi 6 juillet 2023

How to ignore "-W" message on included third party libraries?

I often include external/third party libraries on my C++ projects, and almost everytime they contains -W warning message while compiling my code.

They are located on lib/* folders. Specifically on Makefile, that's what I include:

# Add .h and .hpp to the preprocessor build
HEADERS += $(wildcard lib/*.h)
HEADERS += $(wildcard lib/*.hpp)
HEADERS += $(wildcard lib/**/*.h)
HEADERS += $(wildcard lib/**/*.hpp)
HEADERS += $(wildcard lib/**/**/*.h)
HEADERS += $(wildcard lib/**/**/*.hpp)
HEADERS += $(wildcard src/*.h)
HEADERS += $(wildcard src/*.hpp)
HEADERS += $(wildcard src/**/*.h)
HEADERS += $(wildcard src/**/*.hpp)

# Add .c and .cpp files to the build
SOURCES += $(wildcard lib/*.c)
SOURCES += $(wildcard lib/*.cpp)
SOURCES += $(wildcard lib/**/*.c)
SOURCES += $(wildcard lib/**/*.cpp)
SOURCES += $(wildcard lib/**/**/*.c)
SOURCES += $(wildcard lib/**/**/*.cpp)
SOURCES += $(wildcard src/*.c)
SOURCES += $(wildcard src/*.cpp)
SOURCES += $(wildcard src/**/*.c)
SOURCES += $(wildcard src/**/*.cpp)

# FLAGS will be passed to both the C and C++ compiler
FLAGS +=
CFLAGS +=
CXXFLAGS += $(sort $(foreach HEADERS, $(HEADERS), -I$(dir $(HEADERS))))

Is it possible to specify (I'm using MingGW on Windows, so "gcc") that for that lib/* folder, ignore warning message? Keeping my code/compilation clean? Its pretty boring "mess" with others libraries warning why compiling and check status.

I dont know how to include libraries in cmake

Hellow.I recently started working with cmake, and I need to include the following libraries I know that this is done using the function add_library(),but what should I give s as an argument?Direct path to the library? And what i must do after it?

   #include "opencv2/core/core.hpp"
   #include "opencv2/imgcodecs.hpp"
   #include "opencv2/imgproc.hpp"
   #include "rknn_api.h"

   #include <float.h>
   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>
   #include <sys/time.h>

P.S I'm trying to compile this code rknpu2/examples/rknn_commen_test/src/http://main.cc

Using std::enable_if with complex predicates

Having to use C++14 I'd like to use std::enable_if to make a function only being available given certain constraints. I do so using or_<> taken from the libc header type_traits instead of std::disjunction (no C++17 available in my environment) in order to move the constraint logic into a separate construct.

However, I seem to be missing something, because I can't manage to get it to compile.

My code:

#include <type_traits>
#include <iostream>
#include <vector>
#include <list>

template <typename T>
struct IsVector : public std::false_type {};

template <typename T>
struct IsVector<std::vector<T>> : public std::true_type {};

template <typename T>
struct IsList : public std::false_type {};

template <typename T>
struct IsList<std::list<T>> : public std::true_type {};

// taken from libc type_traits
template <bool, typename, typename>
struct conditional;

template <typename...>
struct or_;

template <>
struct or_<> : public std::false_type {};

template <typename _B1>
struct or_<_B1> : public _B1 {};

template <typename _B1, typename _B2>
struct or_<_B1, _B2> : public conditional<_B1::value, _B1, _B2>::type {};

template <typename _B1, typename _B2, typename _B3, typename... _Bn>
struct or_<_B1, _B2, _B3, _Bn...> : public conditional<_B1::value, _B1, or_<_B2, _B3, _Bn...>>::type {};
// ---

template <typename T>
struct IsVectorOrList : public or_<IsVector<T>, IsList<T>>::type {};

template <typename T>
typename std::enable_if<IsVector<T>::value || IsList<T>::value, void>::type
// replacing with this line does not work
//typename std::enable_if<IsVectorOrList<T>::value, void>::type
foo(const T& list)
{
    for (const auto& item : list)
    {
        std::cout << item << std::endl;
    }
}


int main()
{
    foo(std::vector<int>{17, 42});
    foo(std::list<float>{1.0, 2.71, 3.14});
}

When using typename std::enable_if<IsVector<T>::value || IsList<T>::value, void>::type as constraint it works fine. If I use typename std::enable_if<IsVectorOrList<T>::value>::type the compiler complains:

traits.cpp:32:8: error: invalid use of incomplete type ‘struct conditional<true, IsVector<std::vector<int> >, IsList<std::vector<int> > >’
   32 | struct or_<_B1, _B2> : public conditional<_B1::value, _B1, _B2>::type {};
      |        ^~~~~~~~~~~~~
traits.cpp:20:8: note: declaration of ‘struct conditional<true, IsVector<std::vector<int> >, IsList<std::vector<int> > >’
   20 | struct conditional;
      |        ^~~~~~~~~~~

How do I make it work?

mercredi 5 juillet 2023

What is the difference between C11's constexpr and C23's [[reproducible]]?

C++11 added the constexpr keyword which can be added to functions to specify constant behavior.

C23 added what seems to be identical functionality in the form of the [[reproducible]] tag.

How are these two mechanisms different?

C template function from callable class instance to std::function

I do need std::function for stateful operation.

So I would like to make an instance of a class implementing operator() into std::function. I did test std::bind works, but can't wrap it up as a function.

struct StatefulOperation
{
    StatefulOperation(int num) : num_(num) {}
    int operator()(int i)
    {
        num_ += i;
        return num_;
    }
    
    int num_;
};


// This works

const StatefulOperation obj(40);
    
using std::placeholders::_1;
std::function<int(int)> op = std::bind(&StatefulOperation::operator(), obj, _1);


// Want something like this

template<typename A, typename B, typename C>
std::function<B(A)> op(C& obj);


// This doesn't work

template<typename A, typename B, typename C>
std::function<B(A)> op(C& obj)
{
    using std::placeholders::_1;
    return std::bind(&C::operator(), obj, _1);
}

The last implementation attempt fails with error like below;

main.cpp:52:21: note:   template argument deduction/substitution failed:
main.cpp:75:35: note:   couldn’t deduce template parameter ‘A’
   75 |     std::function<int(int)> f = op(a);
      |                                 ~~^~~

How can I get this done?

RAII using custom deleter of unique_ptr

I want to do automatic cleanup using std::unique_ptr but to initialize the unique_ptr I need an address to point to. How can I avoid the noUse variable?

bool noUse;
auto deleter = [](bool *){ DESTROY_SOMETHING }; 
std::unique_ptr<bool, decltype(deleter)> upp(&noUse, deleter); // I want to avoid the usage of this extra noUse variable
START_SOMETHING

//COMPLEX IF ELSE RETURN LOGIC

How can I pass by reference considering inheritance?

Here's my scenario (notice the code I can edit, the code I cannot):

#include <iostream>

// the follow is untouchable (from sdk)
struct Base { };

template <class TParamQuantity = Base>
TParamQuantity* configParam(int paramId) { }

// the follow is my code (can edit as I want)
struct BaseParamScaler { };
struct LogParamScaler : BaseParamScaler { };

template <BaseParamScaler &T>
struct QRange : Base { };

LogParamScaler gLogParamScaler;

int main()
{
    configParam<QRange<gLogParamScaler>>(0);
}

What I'd like to know is being able to pass BaseParamScaler (and its childs) to configParam template method (which come from sdk).

Is there any way of doing this in C++11? Or how would you do this in some fancy way?

Note: if pass by point/value/whatever is permitted, I can do that way. But I believe stay with template is mandatory, having configParam working with them.

mardi 4 juillet 2023

How to implement a make_rv function in c

I want to write a template which can turn lvalue/rvalue to rvalue using universal reference like std::forward For rvalue, just forward it. For lvalue, copy it.

it is used as below

template<typename T>
void func(T&& arg) {
    f_take_rv(make_rv<T>(arg)); // f_take_rv takes right value only
}

Here is my implement

template<typename T> // for lvalue
constexpr T make_rv(typename std::remove_reference<T>::type& arg) {
    return arg;
}
template<typename T> // for rvalue
constexpr T&& make_rv(typename std::remove_reference<T>::type&& arg) {
    return static_cast<T&&>(arg);
}

However, it always goes to the lvalue one

I also tried std::enable_if to control its type deduction.

template<typename T>
constexpr typename std::enable_if<
    std::is_reference<T>::value,
    typename std::remove_reference<T>::type
>::type make_rv(typename std::remove_reference<T>::type& arg) { return arg; }

template<typename T>
constexpr typename std::enable_if<
    !std::is_reference<T>::value,
    T
>::type&& make_rv(typename std::remove_reference<T>::type&& arg) {
    return static_cast<T&&>(arg);
}

But it failed for literal string, like "str": no matching function for call to 'make_rv<const char(&)[4]>(const char [4])'

Could you tell me how to implement it

gcc implement of std::forward for reference:

template<typename _Tp>  // forwarding an lvalue
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept {
    return static_cast<_Tp&&>(__t);
}
template<typename _Tp>  // forwarding an rvalue
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept {
    return static_cast<_Tp&&>(__t);
}

Explain implementation of function call operator in boost value_factory

I am trying to understand the boost implementation of factory design pattern. Boost provides two types of factory one for pointer types and other for value semantics. I am able to understand a little about the template value_factory class. However I am facing difficulty is understanding how operator()(..) is defined outside class and namespace.

Below is the link to complete code: https://github.com/boostorg/functional/blob/7516442815900430cc9c4a6190354e11bcbe72dd/include/boost/functional/value_factory.hpp

Code snippet after removing lot of includes.

#   ifndef BOOST_PP_IS_ITERATING
namespace boost
{
    template< typename T >  class value_factory;

    template< typename T >
    class value_factory
    {
      public:
        typedef T result_type;
        value_factory()
        { }
    }; // value_factory
    
    template< typename T > class value_factory<T&>;
} // namespace boost
#   else // defined(BOOST_PP_IS_ITERATING)
    template< BOOST_PP_ENUM_PARAMS(0, typename T) >
    inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(0, T, &a)) const
    {
        return result_type(BOOST_PP_ENUM_PARAMS(N,a));
    }
#   endif // defined(BOOST_PP_IS_ITERATING)

This code is from boost version 1.71.

I would like to understand how operator()(...) plays role here

  1. It is outside class
  2. It is defined in 2nd conditional block # else // defined(BOOST_PP_IS_ITERATING)

As per my understanding member function operator()(...) should have been inside the class.

Non-aggregate type 'vector

Installed VSC, downloaded basic extensions for c++, then when working with vectors it gives an error, on the forum it was recommended to insert the command g++ -std=c++11 when the code is compiled, but I don't know where to insert it. The program now has the compiler g++ build and debug active files, most likely the problem is in it, how to change it or fix the error

lundi 3 juillet 2023

Inconsistent results when type punning uint64_t with union and bit-field

I am using an anonymous struct in union as follows:

using time64_t = uint64_t;
using bucket_t = uint64_t;

union clock_test {
    time64_t _time64;

    struct {
        bucket_t _bucket5 : 10;     // bucket:5  1024
        bucket_t _bucket4 : 8;      // bucket:4  256
        bucket_t _bucket3 : 6;      // bucket:3  64
        bucket_t _bucket2 : 6;      // bucket:2  64
        bucket_t _bucket1 : 6;      // bucket:1  64
        bucket_t _bucket0 : 6;      // bucket:0  64
    };
};

If bucket_t = uint64_t, it works as expected, but with using bucket_t = uint16_t or uint32_t, I get puzzling results.

I use the same test code for all cases:

clock_test clk;
clk._time64 = 168839113046;

For bucket_t = uint64_t, clk is:

_bucket5   342  // unsigned __int64
_bucket4    26  // unsigned __int64
_bucket3    38  // unsigned __int64
_bucket2    15  // unsigned __int64
_bucket1    29  // unsigned __int64
_bucket0     2  // unsigned __int64

For bucket_t = uint32_t, clk is:

_bucket    342  // unsigned int
_bucket4    26  // unsigned int
_bucket3    38  // unsigned int
_bucket2    15  // unsigned int
_bucket1    39  // unsigned int
_bucket0     0  // unsigned int

For bucket_t = uint16_t, clk is:

_bucket5    342 // unsigned short
_bucket4    152 // unsigned short
_bucket3     15 // unsigned short
_bucket2     39 // unsigned short
_bucket1      0 // unsigned short
_bucket0      0 // unsigned short

dimanche 2 juillet 2023

How to do this i cannot figure out how to do it

Create a c++ program according to the following requirements: Given a sequence of numbers consisting of a sequence of many elements. What is the number of different elements in the sequence, and how many times each element appears?

Overlaying on english text (chinese / Japanese) on Image with opencv c

Opencv cv::putText doesn't support chinese / japanese (unicode string) to be overlayed on the image.

Any work around we available ?

cv::putText(img, //target image "你好世界", //text cv::Point(10, img.rows / 2), //top-left position cv::FONT_HERSHEY_DUPLEX, 1.0, CV_RGB(118, 185, 0), //font color 2);

But Text written on Image : "??????"

I cannot call operator- function defined outside my class from my class

I came across an issue with overloading operator.. methods. I can call them with no problem but I couldn't call it inside the "reject" method which i don't see why.
I would be very pleased if you explain why. I really appreciate any help you can provide.

ps: when I comment out the reject method I could call the method to print the difference of the vectors but I cannot see why I cannot call them from a static method. I couldn't find any answers and have been thinking for days.

// vector3d.h

namespace gm::data // graphics math
{
    struct Vector3D
    {
       ...  
        // Projection of first onto second vector.
        static inline Vector3D project(const Vector3D &first, const Vector3D &second)
        {
            return (second * (dot(first, second) / dot(second, second)));
        }

        // Reject of first onto second vector.
        static inline Vector3D reject(const Vector3D &first, const Vector3D &second)
        {
            return first - (second * (dot(first, second) / dot(second, second)));
        }
...

    private:
        double xyz[3];
    };

 
    static inline Vector3D operator-(const Vector3D &xyz, const Vector3D &other)
    {
        return Vector3D(xyz[0] - other[0], xyz[1] - other[1], xyz[2] - other[2]);
    }

}


//Test.cc file is below 

const Vector3D vector{1, 2, 3};
const Vector3D vector2{1, 5, 7};

std::cout << vector - vector2 << std::endl;
std::cout << gm::data::operator-(vector, vector2) << std::endl;


In file included from ./src/main.cc:3:
./src/data/vector3d: In member function ‘gm::data::Vector3D gm::data::Vector3D::reject(const gm::data::Vector3D&, const gm::data::Vector3D&)’:
./src/data/vector3d:86:26: error: no match for ‘operator-’ (operand types are ‘const gm::data::Vector3D’ and ‘gm::data::Vector3D’)
   86 |             return first - (second * (dot(first, second) / dot(second, second)));
      |                    ~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                    |               |
      |                    |               gm::data::Vector3D
      |                    const gm::data::Vector3D
In file included from ./test/test.cc:2:
./src/data/vector3d: In member function ‘gm::data::Vector3D gm::data::Vector3D::reject(const gm::data::Vector3D&, const gm::data::Vector3D&)’:
./src/data/vector3d:86:26: error: no match for ‘operator-’ (operand types are ‘const gm::data::Vector3D’ and ‘gm::data::Vector3D’)
   86 |             return first - (second * (dot(first, second) / dot(second, second)));
      |                    ~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                    |               |
      |                    |               gm::data::Vector3D
      |                    const gm::data::Vector3D
make: *** [Makefile:2: all] Error 1

samedi 1 juillet 2023

Why does the correct implementation of std::addressof require compiler support?

From possible implementation of std::addressof on https://en.cppreference.com/w/cpp/memory/addressof, it states that "correct implementation of std::addressof require compiler support". Why is it the case?

I tried out the implementation on https://godbolt.org/z/vnzbs9aTG and it worked as expected.

#include <iostream>
#include <string>
#include <type_traits>

template<class T>
typename std::enable_if<std::is_object<T>::value, T*>::type addressof_impl(T& arg) noexcept
{
    return reinterpret_cast<T*>(
               &const_cast<char&>(
                   reinterpret_cast<const volatile char&>(arg)));
}
 
template<class T>
typename std::enable_if<!std::is_object<T>::value, T*>::type addressof_impl(T& arg) noexcept
{
    return &arg;
}

struct Student {
    std::string name{};
    int age{};
};

int main() {
    Student s;
    std::cout << addressof_impl(s);
    return EXIT_SUCCESS;
}