vendredi 1 février 2019

How to fetch in C++ at compile time the number of elements in an enum? [duplicate]

This question already has an answer here:

Is there a way to fetch the number of elements in an enum in C++11 at compile time? In my case the enum is a ordered bitmask enum, meaning that first element is 0x0000, next element is 0x0001 and so on.

Define copy constructor when keyword "this" is used inside constructor

I am having difficulties while defining the copy constructor of my class TextListener. The class TextListener bind a method callback using this keyword. Please see the complete code below:

#include <iostream>
#include <ros/ros.h>
#include <std_msgs/String.h>

class TextListener {
 private:
  std::string _text;
  ros::Subscriber _subscriber;

 public:
  TextListener() {
    std::cout << "[" << this << "] deafult constructor called" << std::endl;
  }

  TextListener(const TextListener &other)
      : _subscriber(other._subscriber), _text(other._text) {
    std::cout << "[" << this << "] copy constructor called" << std::endl;
  }

  TextListener &operator=(const TextListener &other) {
    std::cout << "[" << this << "] copy assignment called" << std::endl;
    _subscriber = other._subscriber;
    _text = other._text;
    return *this;
  }

  TextListener(ros::NodeHandle &nh, const std::string &topicName) {
    std::cout << "[" << this << "] constructor called" << std::endl;
    _subscriber = nh.subscribe(topicName, 1, &TextListener::callback, this);
  }

  void callback(const std_msgs::String::ConstPtr &msg) { _text = msg->data; }

  std::string &getText() { return _text; }

  ~TextListener() {
    std::cout << "[" << this << "] destructor called" << std::endl;
  }
};

To test the above class, I created an instance of it, which works without any problem. However, when I create a new instance and assign this instance to the new instance, the new instance doesn't work. Below is the code snippet:

int main(int argc, char **argv) {
  ros::init(argc, argv, "tet_listener");

  ros::NodeHandle nh;
  std::string topicName = "chatter";
  TextListener listener(nh, topicName);
  TextListener copyListener = listener;

  ros::Rate loop_rate(1);
  while (ros::ok()) {
    ROS_INFO("I heard: [%s]", copyListener.getText().c_str());
    ros::spinOnce();
    loop_rate.sleep();
  }

  return 0;
}

The method getText() doesn't have any value. See below the output:

[0x7ffc5698a2b0] constructor called
[0x7ffc5698a2d0] copy constructor called
[ INFO] [1549031938.250136695]: I heard: []
[ INFO] [1549031939.250183378]: I heard: []
[ INFO] [1549031940.250170333]: I heard: []
[ INFO] [1549031941.250176834]: I heard: []
^C[0x7ffc5698a2d0] destructor called
[0x7ffc5698a2b0] destructor called

I guess that the copy constructor is missing something. How to define copy constructor when keyword "this" is used inside constructor?

Why is `const T&` not sure to be const?

template<typename T>
void f(T a, const T& b)
{
    ++a; // ok
    ++b; // also ok!
}

template<typename T>
void g(T n)
{
    f<T>(n, n);
}

int main()
{
    int n{};
    g<int&>(n);
}

Please note: b is of const T& and ++b is ok!

Why is const T& not sure to be const?

Why does universal reference not keep constness of its arguments?

template<typename T>
void f(T&& n)
{
    ++n; // ok to modify a const object, why?
}

template<typename T>
void g()
{
    int n{};
    f<const T&>(n);
}

int main()
{
    g<int&>();
}

As shown in the code above. My question is:

Why does universal reference not keep constness of its arguments?

Callbacks and `std::recursive_mutex` - valid use case?

I have the following polymorphic interface:

struct service
{
    virtual void connect(std::function<void>(bool) cb);
      // Invoke 'cb' with 'true' on connection success, 'false' otherwise.

    virtual ~service() { }
};

Some implementations of service are synchronous:

struct synchronous_service : service
{
    void connect(std::function<void>(bool) cb) override
    {
        cb(true);
    }
};

Others are asynchronous:

struct asynchronous_service : service
{
    void connect(std::function<void>(bool) cb) override
    {
        _thread_pool.post([this, cb]{ cb(true); });
    }
};

I need to create a service wrapper, which is a service itself. This needs to be thread-safe and maintain some state under a mutex:

struct wrapped_service : service 
{
    state                    _state;
    std::mutex               _mutex;
    std::unique_ptr<service> _underlying;

    void connect(std::function<void>(bool) cb) override
    {
        std::lock_guard<decltype(_mutex)> guard;
        // update `_state`

        _underlying->connect([this, cb]
        {
            std::lock_guard<decltype(_mutex)> guard;
            // update `_state`
            cb(true);
        });

        // update `_state`
    }
}

If the _underlying->connect call is always asynchronous, then std::mutex will work fine. However, in the case that _underlying->connect is synchronous, the program will freeze.

This can be solved by using std::recursive_mutex instead of std::mutex, but it's generally known that it is a code smell.

Is this a valid use case for an std::recursive_mutex?

Or is the design flawed? Note that I have no control over the service interface.

My integer insertion program in a chaining transforms integers from 16: (2,4,6,8,10,12,14,875311656,942421548,741355820)

Here is my insert method of a chaining class that I implement, the data type is integer (typedef int TELEM).By displaying the numbers stored, from 16 shows me other values too big

class list


private : 
     TELEM m_nb;
     TELEM *m_numbers;
public :
     ...//construc,destruct,methods

void list::insert(const TELEM& e, int i)
{  
  assert((i>=1) && (i<=m_nb+1));

  for (int k = m_nb ; k >= i ; --k)
    m_numbers[k+1] = m_numbers[k];      
  m_numbers[i] = e;
  std::cout << e <<std::endl;
  std::cout << m_numbers[i] <<std::endl;

  m_nb++;

}

for (int i=1; i<=10; ++i)
   myliste.insert(2*i,i);

from 16 ca gives me this (2,4,6,8,10,12,14,875311656,942421548,741355820) instead (2,4,6,8,10,12,14,16,18,20)

Avoiding a copy constructor call when returning the constructed object by value in C++11

I have a class without a copy constructor, which I still want to return by value. The following MCVE compiles in C++17:

class Cls {
    public:
    Cls(int x) {}
    Cls(const Cls& c) = delete;
};

Cls f(int x) {
    return Cls(x);
}

int main() {
    f(0);
}

but not in C++11:

$ g++ prog.cc -Wall -Wextra -std=c++11
prog.cc: In function 'Cls f(int)':
prog.cc:9:17: error: use of deleted function 'Cls::Cls(const Cls&)'
    9 |     return Cls(x);
      |                 ^
prog.cc:5:5: note: declared here
    5 |     Cls(const Cls& c) = delete;
      |     ^~~

As I understand it, the reason is that the compiler is allowed not to optimize the copy out, even if it should be trivial in this case.

I was hoping return std::move(Cls(x)); would work and avoid the copy constructor, but it gives the same error.

Can I fix the problem without defining the copy constructor (or the assigment operator)?

I've looked through related questions, but couldn't find a duplicate.