使用gcc的C ++部分模板特化问题

时间:2017-06-19 09:57:34

标签: c++ c++11 gcc clang template-meta-programming

我正在尝试使用模板部分特化在编译时计算GCD。 以下代码适用于clang3.8但不适用于gcc7.1。使用GCC,它将进入递归模板实例化而不会实现终止案例。

template <int N, int M>                                                                                                                                              
struct GCD{                                                                                                                                                          
    static const int value = (N>M)? GCD<N%M, M>::value : GCD<N, M%N>::value;                                                                                         
};                                                                                                                                                                   

template <int M>                                                                                                                                                     
struct GCD<0, M>{                                                                                                                                                    
    static const int value = M;                                                                                                                                      
};                                                                                                                                                                   

template <int M>                                                                                                                                                     
struct GCD<M, 0>{                                                                                                                                                    
    static const int value = M;                                                                                                                                      
};                                                                                                                                                                   


int main()                                                                                                                                                           
{                                                                                                                                                                    
    static_assert(GCD<12,15>::value == 3, "Error");                                                                                                                          
} 

谁在这里表现得很清醒?

1 个答案:

答案 0 :(得分:1)

如果您想解决问题,我建议进行以下改进

template <int N, int M, bool = (M != 0) && (N != 0) && (N > M)>
struct GCD;

template <int N, int M>
struct GCD<N, M, true>
 { static constexpr int value { GCD<N%M, M>::value }; };

template <int N, int M>
struct GCD<N, M, false>
 { static constexpr int value { GCD<N, M%N>::value } ; };

template <int M>
struct GCD<0, M, false>
 { static constexpr int value { M }; };

template <int M>
struct GCD<M, 0, false>
 { static constexpr int value { M }; };

如果你想知道g ++或clang ++是对的,那么......我不知道编译器在这种情况下可以或必须做什么,所以...我不知道

确切地说,当N > M与编译器相遇时,我不知道

     static const int value = (N>M)? GCD<N%M, M>::value : GCD<N, M%N>::value;                                                                                                                                                                                               

如果编译器必须(或可以)只实现GCD<N%M, M>或者必须(或可以)实现GCD<N, M%N>

无论如何,如果我没错,clang ++只实现GCD<N%M, M>,其中g ++实现两者。

我的改进旨在避免这个问题。