tags:

views:

74

answers:

2

Why executing this code:

// DefaultAny.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <exception>

using std::cout;

template<class T>
struct NoReturnPolicy 
{
    static void calculate(T& result, const T& source)
    {
        result = source;
    }
};

template<class T>
struct ReturnPolicy 
{
    static T& calculate(T& result, const T& source)
    {
        result = source;
        return result;
    }
};


template<class T>
struct ThrowPolicy 
{
    static void check(T* ptr)
    {
        cout << "ThrowPolicy";
        struct Nullptr: public std::exception{};

        if(!ptr)
        {
            throw Nullptr("Nullptr not allowed"); 
        }
    }
};

template<class T>
struct NoThrowPolicy 
{
    static T* check(T* ptr)
    {
        cout << "NoThrowPolicy";
        if(!ptr)
        {
            return nullptr;
        }
        else
        {
            return ptr;
        }
    }
};


/*
If pointer already points at 
something no assignement is being done
*/
template<class T, class ThrowingPolicy>
struct NoAssignPolicy 
{
    static T* check(T* dest,const T*const src)
    {
        cout << "NoAssignPolicy";
        if (!ThrowPolicy::check(dest))
        {
            dest = operator new(sizeof(T));
            new (dest) T(*src);
        }

    }
};

template<class T,class ThrowingPolicy>
struct NoCheckPolicy
{
    static void check(T* p)
    {
        cout << "NoCheckPolicy";
    }
};


template<class T,class ThrowingPolicy>
struct CheckPolicy
{
    static void check(T* p)
    {
        cout << "CheckPolicy";
        ThrowingPolicy::check(p);
    }
};


template<
         class T,
         class ThrowingPolicy = NoThrowPolicy<T>,
         class CheckingPolicy = NoCheckPolicy<T,ThrowingPolicy>,  
         class AssigningPolicy = NoAssignPolicy<T,ThrowingPolicy>,
         class ReturningPolicy = NoReturnPolicy<T>
        >
struct BreadSlicer
{
    BreadSlicer()
    {
        cout << "Type: " << typeid(T).name() << '\n';
            cout << "ThrowingPolicy: " << ThrowingPolicy::check(0) << '\n'; //  
//<<<---------The second call to cout makes output on my console:  
//NoThrowPolicy:"NoSpace"ThrowingPolicy:"Space"000000
        }
    };

    //The words NoSpace and Space do not actually appear in my console ;) and they are in the opposite order.



int _tmain(int argc, _TCHAR* argv[])
{
    BreadSlicer<int> a;
    return 0;

}

See comments in first struct above main.

+3  A: 

If your question is why "NoThrowPolicy" gets output before "ThrowingPolicy", the answer is that there's no sequence point guaranteeing an ordering for the call to ThrowingPolicy::check(0) and the call to operator<<(cout, "ThrowingPolicy: "). C++ is allowed to call those functions in either order.

aschepler
+4  A: 

This is the result of unspecified behavior. If you have:

cout << a() << b() << c() << endl;

The order of execution of a, b, and c is not defined (yes, their results are added to the cout stream in a predictable order, but execution of the functions is not in defined order).

JoshD
The behavior is not undefined. The behavior is _unspecified_. There's a big difference.
James McNellis