2

I have a custom class producer which inherits from SystemC class sc_module:

class producer: public sc_module {
    public:
        int counter;
        sc_in<bool> clock;
        sc_out<msg> out;
        int speed;

        producer(sc_module_name name, int speed) : 
            sc_module(name), 
            speed(speed) 
        {
            SC_HAS_PROCESS(producer);
            SC_METHOD(produce);

            sensitive << clock.pos();
            counter = 0;
        }

        void produce() {
            ...
        }

};

Later in the SystemC sc_main-class I want to put a bunch of objects in a std::vector<producer>:

std::vector<producer> producers;
for(int i = 0; i < numIn; i++){
    producers.at(i) = producer("Producer " + i, genSpeed); // <- Here the error occurs
}

And here is the compiler error:

error: use of deleted function ‘producer& producer::operator=(producer&&)’
         producers.at(i) = producer("Producer " + i, genSpeed);
                                                             ^
dist.cpp:103:7: note: ‘producer& producer::operator=(producer&&)’ is implicitly deleted because the default definition would be ill-formed:
 class producer: public sc_module {
       ^~~~~~~~

Why does the error occur? How can I fix it?

goulashsoup
  • 2,639
  • 2
  • 34
  • 60
  • Are you sure the produer / sc_module class is copyable, I have the suspicion that `producers.at(i) = producer("Producer " + i, genSpeed);` is trying to copy-assign a non-copyable type, which is resulting in your error. – Gio Dec 14 '16 at 17:57
  • @Gio Well I assume that has something todo with the parent class `sc_module`. How can I find out if its copyable? [Here](http://www.lysium.de/docs/systemc-2.2/docs/html/classsc__core_1_1sc__module.html) is the class reference... – goulashsoup Dec 14 '16 at 18:02
  • Are sc_in<> and sc_out <> movable? – Shyamal Desai Dec 14 '16 at 18:03
  • @ShyamalDesai I don´t think so. Here is the class reference of [`sc_in<>`](https://www.iro.umontreal.ca/~lablasso/docs/SystemC2.0.1/html/classsc__in.html) – goulashsoup Dec 14 '16 at 18:38
  • You class is copyable if it has a copy constructor. *Usually if a copy constructor is not defined in a class, the compiler itself defines one. *(A specific class definition might specify it as non-copyable, see [here](http://stackoverflow.com/questions/2173746/how-do-i-make-this-c-object-non-copyable)). ps. your link does not work. – Gio Dec 14 '16 at 18:39

3 Answers3

3

Copy construction and assignment are disabled for sc_modules to implement/preserve SystemC elaboration semantics.

You should use sc_vector to create collections of sc_objects. It was created specifically to address this type of design problems.

random
  • 3,868
  • 3
  • 22
  • 39
2

producer doesn't have a move assignment operator. By the looks of things, probably because sc_module doesn't have one.

You have other problems:

std::vector<producer> producers;
for(int i = 0; i < numIn; i++){
    producers.at(i) ....
}

This creates an empty vector of producers, and then assigns to the first element of that vector. The problem is that there is no such element, and because you are using at, you will get an exception.

Conveniently, you can fix both problems at once with:

std::vector<producer> producers;
for(int i = 0; i < numIn; i++){
    producers.emplace_back("Producer " + i, genSpeed);
}

This creates an empty vector, and then constructs a series of new producers at the end of it. This does depend on you having a working move constructor. If you don't have a working move constructor, I think you are rather stuck.

This still won't work, because you will get producers called "Producer ", "roducer ", "oducer ", etc. Adding an integer to a character string literal will just return a pointer to the n'th character of the literal. What you need is to make the literal be a std::string literal, and convert the integer to text.

    producers.emplace_back("Producer "s + std::to_string(i), genSpeed);
Quentin
  • 62,093
  • 7
  • 131
  • 191
  • Your final solution does not work : `error: no matching function for call to ‘producer::producer(std::__cxx11::basic_string, int&)’`. Maybe because producers `name` attribute is of type [`sc_module_name`](http://www.lysium.de/docs/systemc-2.2/docs/html/classsc__core_1_1sc__module__name.html)... For other `sc_module` classes something like `"name" + i` (with `i` is in integer) does work, but with `producers.emplace_back("Producer " + i, genSpeed);` I get the error `error: use of deleted function ‘producer::producer(producer&&)’` – goulashsoup Dec 14 '16 at 18:18
0

I our final solution we used std::shared_ptr and std::vector:

using sharedProducerPointer = std::shared_ptr<producer>;
std::vector<sharedProducerPointer> producers;

//bind producers and distributor to input signals
for(int i = 0; i < numIn; i++) {
    std::string stringProducersName = "producer_" + std::to_string(i);
    const char* charProducersName = stringProducersName.c_str();

    sharedProducerPointer prod = sharedProducerPointer(new producer(charProducersName, genSpeed, numOut));
    prod->out.bind(inputSignals.at(i));
    dist.inputMsg.at(i).bind(inputSignals.at(i));
    prod->clock(inClock);

    producers.push_back(prod);
}
goulashsoup
  • 2,639
  • 2
  • 34
  • 60