2017-09-07 5 views
0

Ma question est naïve mais aidez-moi à comprendre si mon raisonnement est correct. Voici le code que je développe après avoir regardé une partie d'une vidéoconférence de Walter E. Brown sur la métaprogrammation. Le code fonctionne. Ma question est plus sur la façon dont le compilateur correspond et évalue les expressions.Comment complier trouve le modèle le mieux correspondre et évalue les expressions

//1 - Matches "simple" type. 
template <typename T_> 
struct mySizeof 
{ 
    static constexpr size_t size = sizeof(T_); 
}; 

//2 - Matches arrays of type T_ and size N. 
template <typename T_,size_t N> 
struct mySizeof<T_[N]> 
{ 
    //3 - What is T_ at this point??? 
    static constexpr size_t size = N * mSize<T_>::size;  
}; 

int main() 
{ 
    using int_t = int; 
    using int_arr = int[10][50][100]; 

    std::cout << mySizeof<int_t>::size << ":" << sizeof(int_t) << std::endl; 
    std::cout << mySizeof<int_arr>::size << ":" << sizeof(int_arr) << std::endl; 

    return 0; 
} 

//Parsing & evaluating int [10][50][100] 
// 1.1 - Matches T_ = int[10][50][100]. But there's a better match. 
// 1.2 - Better match. T_ = int, N = 10. 
// 1.3 - Since [10] was consumed, lets check the remain expression. T_ becomes [50][100]. ??? 
// 2.1 - Matches T_ = int[50][100]. There's a better match. 
// 2.2 - Better match. T_ = int, N = 50. 
//.... 
// 4.1 - It matches. T_ -> int 
// 4.2 - Doesn't match. 

J'ai juste besoin de comprendre à ce stade comment le compilateur évalue et trouve le meilleur match, et comment faut-il procéder à la substitution des arguments.

+0

est 'mSize' censé être' mSizeof' ? – Yakk

Répondre

2

Après votre schéma

Parsing & évaluation int [10][50][100]

1.1 - Matchs T_ = int[10][50][100]. Mais il y a un meilleur match. [right]

1.2 - Meilleure correspondance. T_ = int, N = 10. [wrong: N=10, T_=int[50][100]]

1.3 - Puisque [10] a été consommée, vérifions l'expression restante. T_ devient [50][100]. [T_ = int[50][100], voir 1.2]

2.1 - Correspondances T_ = int[50][100]. Il y a un meilleur match. [right]

2.2 - Meilleure correspondance. T_ = int, N = 50. [faux: N=50 and T_=int[100]]

....

4,1 - Il correspond. T_ ->int [right]

4.2 - Ne correspond pas. [Droite]

(ps:. Si je ne me trompe pas, SFINAE ne participe pas, seule spécialisation)

Un simple test

#include <iostream> 
#include <type_traits> 

template <typename T> 
struct mySizeof 
{ static constexpr std::size_t size { sizeof(T) }; }; 

template <typename T, std::size_t N> 
struct mySizeof<T[N]> 
{ 
    static constexpr size_t size { N * mySizeof<T>::size };  
    using type = T; 
}; 

int main() 
{ 
    using T0 = int[10][50][100]; 

    using T1 = typename mySizeof<T0>::type; 
    using T2 = typename mySizeof<T1>::type; 
    using T3 = typename mySizeof<T2>::type; 

    static_assert(std::is_same<int[50][100], T1>::value, "!"); 
    static_assert(std::is_same<int[100],  T2>::value, "!"); 
    static_assert(std::is_same<int,   T3>::value, "!"); 
} 
+0

@ max66 Appréciez votre aide. C'est maintenant clair comme du cristal .. –