2010-10-05 4 views
-1

Почему выполнения этого кода:Странно? Поведение соиЬ

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

} 

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

ответ

5

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

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

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

+0

Поведение не определено. Поведение - не указано. Есть большая разница. –

3

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

Смежные вопросы