2010-10-05 5 views
-1

Pourquoi exécuter ce code:Étrange? comportement de Cout

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

} 

Voir les commentaires en premier struct ci-dessus principale.

Répondre

5

Ceci est le résultat d'un comportement non spécifié. Si vous avez:

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

L'ordre d'exécution a, b, et c est pas défini (oui, leurs résultats sont ajoutés au flux de Cout dans un ordre prévisible, mais l'exécution des fonctions est pas défini commande).

+0

Le comportement n'est pas indéfini. Le comportement est _unspecified_. Il y a une grande différence. –

3

Si votre question est pourquoi "NoThrowPolicy" obtient une sortie avant "ThrowingPolicy", la réponse est qu'il n'y a pas de point de séquence garantissant une commande pour l'appel à ThrowingPolicy::check(0) et l'appel à operator<<(cout, "ThrowingPolicy: "). C++ est autorisé à appeler ces fonctions dans n'importe quel ordre.