-4

So I have a problem. My objective is to iterate through sigly linked list I've created. I want to use std::string as an argument to if statement like listed below. I know it's not a good idea, even more: I know it may be the WORST possible way to do this. It doesn't matter I want to know if it can be done. I tried using macro function but either I'm doing it wrong or it's not possible using such macro. Help me please. I'm out of ideas...

Similar macros I used in my old project where I've passed as parameter a name of function (user typed the name of such function like 'sin' or 'tan') from cmath lib to calculate integral for given function, so I thought it would work in this case as well but apparently not. It says:

conditional expression of type 'std::string' is illegal

//structures.h    
struct node
{
    int _value;
    node *pNext;
};


//functions.cpp
#define retarded_at(x) x
#define retarded_stringify(y) retarded_at(y)

//@param pHead pointer to first element of the list
void retDispIter(node *pHead)
{
    std::string at{ "pHead->pNext" };

    while (retarded_at(at))
    {
        at += "->pNext";
        //here send node->_value to std::cout
    }
}

Inside first while loop "at" would be 'pHead->pNext' poining at next element. With 8 elements in the list the last while would be like:

while(pHead->pNext->pNext->pNext->pNext->pNext->pNext->pNext->pNext)

return false and "at" would contain a 'pointer' (nullptr) to the non-existing 9th element.

Robert Andrzejuk
  • 5,076
  • 2
  • 22
  • 31
  • 5
    It's not merely "not a good idea". C++ simply does not work this way. – Sam Varshavchik Dec 20 '18 at 17:05
  • 2
    Are you trying to get some sort of `eval`-like function? That's not possible in C++. – Quentin Dec 20 '18 at 17:05
  • 1
    You knew this was "a bad idea" and now you know that it's not possible. You say "it doesn't matter" but it really does. Why don't you tell us what you're _really trying to accomplish_ and we can help you find a good solution? Walking a linked list is straightforward without `eval`. – TypeIA Dec 20 '18 at 17:13
  • Your problem is unclear. Please explain the issue in a different way. – Robert Andrzejuk Dec 20 '18 at 17:26
  • I know how to normally iterate through a list or how to do it recursively but i want to do it that way... For fun really. I'm curious if it's somehow possible. – Wiktor Utracki Dec 20 '18 at 17:27
  • 1
    Somewhat related to/duplicate of [Is there C/C++ equivalent of eval("function(arg1, arg2)")?](https://stackoverflow.com/questions/11078267/is-there-c-c-equivalent-of-evalfunctionarg1-arg2) – TrebledJ Dec 20 '18 at 17:30
  • Not sure what is unclear Robert. I'm trying to iterate through a list using string variable. To write while(at) and to make compiler see it like this: while(pHead->pNext->pNext...->pNext) – Wiktor Utracki Dec 20 '18 at 17:31
  • @WiktorUtracki No, that's not possible in c++. – πάντα ῥεῖ Dec 20 '18 at 17:31
  • Hm... yeah I'm affraid that it's not indeed.. Thanks panta rei. – Wiktor Utracki Dec 20 '18 at 17:34
  • How about creating an iterator for your list? (precisely : a forward iterator) – Robert Andrzejuk Dec 20 '18 at 17:46
  • To expand on *why* it's impossible, the names `pHead` and `pNext` aren't available to the program at run time; they might be in the executable file but only as debug information. The parser for `operator->` is certainly not available at run time. Since you modify the string at run time, there's no way a macro could see inside it. The C preprocessor doesn't support de-stringification anyway, but if it did it would only work on string literals, not runtine strings. – Daniel H Dec 20 '18 at 17:57
  • Robert Andrzejuk I don't know how to create an iterator really - I heard it's not exactly a pointer but somewhat similar... but thanks I'll read sth about it and try to do it. – Wiktor Utracki Dec 20 '18 at 22:06
  • @Daniel H Thanks!! You are right... didn't think about it really... – Wiktor Utracki Dec 20 '18 at 22:07

2 Answers2

0

C++ is not like matlab or python. It won't compile strings or lines of code in run-time. So no, you cannot use strings this way.

Check out the differences by googling "compiler vs interpreter". C++ is compiler based while python is interprer based. Users of C++ generated programs do not need to have all the build tools to run them.

ALX23z
  • 4,456
  • 1
  • 11
  • 18
0

What You want to acheive is not possible in the way that You are requesting:

  • C++ cannot execute "text" created at runtime, all code has to be available at compile time, so it can be compiled into the target machines - machine code,
  • during runtime, symbols (names of variables, classes, functions, ...) are not used by the machine code (Symbols are converted to addresses and registers and address offsets)

The simplest way to get this to work is:

//@param pHead pointer to first element of the list
void retDispIter(node *pHead)
{
    node* current_node = pHead;

    while (current_node)
    {
        //here send current_node->_value to std::cout

        current_node = current_node->pNext;
    }
}

Another way is to make a very simple iterator class;

struct node_iterator
{
    node* current;

    node_iterator operator++()
    {
        node* temp = current;
        current    = current->pNext;
        return node_iterator { temp };
    }

    node_iterator& operator++(int)
    {
        current = current->pNext;
        return *this;
    }

    node*    operator->() const { return current; }
    node&    operator*() const { return *current; }
    explicit operator bool() const { return current != nullptr; }

    bool     operator==(const node_iterator& other) const { return current == other.current; }
    bool     operator!=(const node_iterator& other) const { return !(*this == other); }
};

Then it can be used like this:

//@param pHead pointer to first element of the list
void retDispIter(node* pHead)
{
    node_iterator iter { pHead };

    while (iter)
    {
        // usage
        std::cout << iter->_value;
        std::cout << (*iter)._value;

        // get next 
        ++iter;
    }
}
Robert Andrzejuk
  • 5,076
  • 2
  • 22
  • 31