Asked  7 Months ago    Answers:  5   Viewed   28 times

the following code:

myQueue.enqueue('a');
myQueue.enqueue('b');
cout << myQueue.dequeue() << myQueue.dequeue();

prints "ba" to the console

while:

myQueue.enqueue('a');
myQueue.enqueue('b');
cout << myQueue.dequeue();
cout << myQueue.dequeue();

prints "ab" why is this?

It seems as though cout is calling the outermost (closest to the ;) function first and working its way in, is that the way it behaves?

 Answers

72

There's no sequence point with the << operator so the compiler is free to evaluate either dequeue function first. What is guaranteed is that the result of the second dequeue call (in the order in which it appears in the expression and not necessarily the order in which it is evaluated) is <<'ed to the result of <<'ing the first (if you get what I'm saying).

So the compiler is free to translate your code into some thing like any of these (pseudo intermediate c++). This isn't intended to be an exhaustive list.

auto tmp2 = myQueue.dequeue();
auto tmp1 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
tmp3 << tmp2;

or

auto tmp1 = myQueue.dequeue();
auto tmp2 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
tmp3 << tmp2;

or

auto tmp1 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
auto tmp2 = myQueue.dequeue();
tmp3 << tmp2;

Here's what the temporaries correspond to in the original expression.

cout << myQueue.dequeue() << myQueue.dequeue();
|       |               |    |               |
|       |____ tmp1 _____|    |_____ tmp2 ____|
|                       |
|________ tmp3 _________|
Tuesday, June 1, 2021
 
CodeCaster
answered 7 Months ago
89
  • Construction always starts with the base class. If there are multiple base classes then, construction starts with the left most base. (side note: If there is a virtual inheritance then it's given higher preference).
  • Then the member fields are constructed. They are initialized in the order they are declared
  • Finally, the class itself is constructed
  • The order of the destructor is exactly the reverse

Irrespective of the initializer list, the call order will be like this:

  1. Base class A's constructor
  2. class B's field named a (of type class A) will be constructed
  3. Derived class B's constructor
Sunday, June 6, 2021
 
iceduck
answered 7 Months ago
89

Here's a simple implementation that will put it all together.

class WinRadioWrapper
{
    public delegate void CallbackFunc( IntPtr pData );

    [DllImport( "WRG305API.dll" )]
    public static extern bool CodecStart( int hRadio, CallbackFunc func, IntPtr CallbackTarget );

    public bool CodecStartTest(int hRadio)
    {
        bool bStarted = CodecStart( hRadio, MyCallbackFunc, IntPtr.Zero );
        return bStarted;
    }

    // Note: this method will be called from a different thread!
    static void MyCallbackFunc( IntPtr pData )
    {
        // Sophisticated work goes here...
    }
}
  • Note that because MyCallbackFunc will be executed on a different thread, I chose to make is static. This way you won't be tempted to access WinRadioWrapper data members.

  • For simplicity I passed an IntPtr.Zero parameter to the callback, but this can point to any data that you'd like to use in the callback.

    [Please ignore this paragraph] Look into Marshal.StructureToPtr if you'd like to pass data to the callback, but make sure to also pin the data that you're passing in order to make sure it's not garbage-collected (see GCHandle for more details).

EDIT:
With the interesting words by svick (thanks!), I realize I was mixing a copied object with a pinned one.
So, to sort things out:

  • Marshal.StructureToPtr should be used if you want to copy an existing data structure and then pass it to the callback function.
  • If, on the other hand, you'd like to use and existing data structure (e.g. for modifying its content), the you should use GCHandle in order to pin it in memory and prevent it from being garbage-collected.
    This, however, will add some maintenance overhead for the GCHandle.
Tuesday, August 17, 2021
 
mariaoialvarez
answered 4 Months ago
87

std::cout is an instance of std::ostream, and, before C++11, that had a conversion operator to void*. It seems your code is triggering that conversion, giving you the address of the std::cout object.

Sunday, August 22, 2021
 
godot
answered 4 Months ago
38

Problems:

  1. You have some missing #includes, which probably caused your initial compiler errors.
  2. You have a simple syntax error with your if statement.
  3. Using the stream extraction operator will never yield a string with whitespace inside of it.

The following should work as you expect:

#include "stdafx.h"
#include <iostream>
#include <ostream>
#include <string>

using namespace std;

int main()
{
    cout << "Input your name please?" << endl;

    string name;
    getline(cin, name);
    if (name == "Bart Simpson")
    {
        cout << "You have been very naughty" << endl;
    }

    return 0;
}

(You need to include string for std::string and std::getline, and ostream for std::endl.)

Thursday, September 2, 2021
 
showstealer
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share