C++ GCC 的部分模板专用化问题

C++ partial template specialization issue with gcc

本文关键字:专用 问题 GCC C++      更新时间:2023-10-16

我正在尝试在编译时使用模板部分专用化来计算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");                                                                                                                          
} 

谁在这里表现得理智?

如果你想解决问题,我提出以下改进

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++ 实现两者。

我的改进是为避免这个问题而量身定制的。