Странный?поведение кут - PullRequest
0 голосов
/ 05 октября 2010

Зачем выполнять этот код:

// 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;

}

См. Комментарии в первой структуре выше main.

Ответы [ 2 ]

5 голосов
/ 05 октября 2010

Это результат неопределенного поведения.Если у вас есть:

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

Порядок выполнения a, b и c не определен (да, их результаты добавляются в поток cout в предсказуемом порядке, но выполнение функций не выполняетсяв определенном порядке).

3 голосов
/ 05 октября 2010

Если ваш вопрос заключается в том, почему «NoThrowPolicy» получает выходные данные перед «ThrowingPolicy», ответ заключается в том, что нет точки последовательности, гарантирующей порядок для вызова на ThrowingPolicy::check(0) и вызова на operator<<(cout, "ThrowingPolicy: "). C ++ может вызывать эти функции в любом порядке.

...