'C++/CLI expression must be an lvalue or a function designator

For my homework I have to create an array with 10 purses and initialize 10 threads to start working individually on each purse by removing coins from one purse and add coins to another

this is what I got so far

#include <time.h>
#include <cstdlib>
#include <cliext/list>
using namespace System::Collections::Generic;
using namespace System;
using namespace System::Threading;



public ref struct Coin {
    String^ name;
    double value;

    Coin(String^ name,double value) {
        this->name = name;
        this->value = value;
    }
};

public ref class Purse{

private:
     static System::Collections::Generic::List<Coin^>^ holder =  gcnew List<Coin^>;
    

public:
    //default constructor creates an empty vector to store coins
    Purse(){
        
    }

    Purse(Coin^ c , int n) {
        addCoin(c, n);
    }

    //method to add coins to our vector holder in purse class
    void static addCoin(Coin^ c , int n ) {
        int i = 0;
        while (i != n) {
            holder->Add(c);
            i++;
            
        }
        Console::WriteLine(n + " coins of name: " + c->name + " and value:" + c->value + " added");
    }

    /*method to remove coins from our holder
    * @param Coin c, the type of coin we want to remove
    * @param int n, how many coins we want to remove
    */
    void removeCoin(Coin^ c, int n) {
        int counter = n;
        
            for (int i = 0; i <= holder->Count - 1; i++) {
                while(counter > 0 ){
                    if (compareCoin(c, holder[i])) {
                        holder->RemoveAt(i);
                        counter--;
                    }

                }
            }
            Console::WriteLine(n + " coins of name: " + c->name + " and of value:" + c->value + " removed");
        }

    

    

    /*Method to returns how many coins of the same kind are in the purse
    * @param Coin c, the type of coin we want to know how many there are 
    */
    int count(Coin^ c) {
        int count = 0;
        for each (Coin^ coin in holder) {
            if(compareCoin(coin , c)) {
                count++;
            }
        }
        return count;
    }

    /*Method to returns the total sum of all coin values in the purse
    */
    double sumCoins() {
        double sum = 0;
        for each (Coin^ coin in holder) {
            sum += coin->value;
        }
        return sum;
    }

    /*Method to returns how many total coins of any kind are in the purse  */
    int totalCoins() {
        int total = 0;
        for each (Coin^ coin in holder) {
            total += 1;
        }
        return total;
    }
    
    /*Method to print each coins name and value*/
    void print() {
        for each (Coin^ coin in holder) {
            Console::WriteLine("coin name: " + coin->name + ", Coin value: " + coin->value);
        }
    }

    /*method to remove coins from our holder
    * @param Coin c1, coin to compared 
    * @param Coin c2, coin to compared
    */
    bool compareCoin(Coin^ c1 , Coin^ c2) {
            if (c1->name == c2->name && c1->value == c2->value) {
                return true;
            }
            return false;
    }

    
};


int main() {
    
    //Create two coins of different type and value
    Coin^ quarter = gcnew Coin("quarter", 0.25);
    Coin^ penny = gcnew Coin("penny", 0.1);
    
    //Create an array to hold 10 purses
    array<Purse^>^ purses = gcnew array<Purse^>(10);
    
    //Initialize 10 purses and add the same amount of coins to each
    for (int i = 0; i < 10; i++) {
        purses[i] = gcnew Purse();
        ThreadStart^ threadDelegate = gcnew ThreadStart(purses[i], &Purse::addCoin(quarter,1));
        Thread^ t = gcnew Thread(threadDelegate);
        
        
    }

    for (int i = 0; i < 10; i++) {
        purses[i]->print();
    }
    
    }

I have an error that says expression must be an lvalue or a function designator when I try to call the add method &Purse::addCoin(quarter,1) on each thread



Solution 1:[1]

ThreadStart is a delegate that takes no parameters, and returns void. The general syntax for creating that delegate object is gcnew ThreadStart(&class::staticMethod) or gcnew ThreadStart(objectToCallMethodOn, &class::instanceMethod). Note that there's no parens after either of the method names: You're taking the address of the method, not invoking it.

Right now, I'm not sure exactly what the fix for your application would be: It looks like you're trying to use addCoin as the thread method, but it's static, not instance, so you wouldn't have an "objectToCallMethodOn" when creating the delegate. Also, the addCoin method takes a couple parameters, and as I said above, ThreadStart is a delegate that takes no parameters.

If you need to pass data to your thread method, you'll probably want to look at ParameterizedThreadStart. That delegate takes a single parameter of type Object. You would still create the delegate in the same way (specifying the object and method only, not the parameter), but then when you start the thread, you pass the object to the Thread::Start(Object) method. Since it looks like you need to pass both a Coin and an integer, you'd make a little class with two fields, and pass that as the start parameter.


All that said, I feel I must mention something about the language: You said that this was a homework problem. C++/CLI is not the best language for learning. C++/CLI is intended as an interface language, to allow C# code to call C++; it's not intended to be a primary development language. C++/CLI has all the complexities of C++, all the complexities of C#, and some added complexities all its own.

If you're learning, I would recommend either C++ for native code, or C# for managed code.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 David Yaw