gcc 的 C++ 部分模板专业化问题

Posted

技术标签:

【中文标题】gcc 的 C++ 部分模板专业化问题【英文标题】:C++ partial template specialization issue with gcc 【发布时间】:2017-06-19 09:57:34 【问题描述】:

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

谁在这里表现得理智?

【问题讨论】:

也许只做两个参数GCD结构的前向声明,定义在特化下面。因为在第一次定义时,编译器并不真正了解这两个专业。我不知道哪个编译器是正确的。 请注意,在 C++17 中,&lt;numeric&gt; 标头中会有一个 gcd 函数。 你的数学在这里不行。 【参考方案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 &gt; M和一个编译器遇到时,

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

如果编译器必须(或可以)只实现GCD&lt;N%M, M&gt;,或者如果必须(或可以)也实现GCD&lt;N, M%N&gt;

无论如何,如果我没记错的话,clang++ 只实现 GCD&lt;N%M, M&gt; 而 g++ 两者都实现。

我的改进是为了避免这个问题。

【讨论】:

你说得对,gcc 两者都实现了。 gcc.gnu.org/bugzilla/show_bug.cgi?id=81134

以上是关于gcc 的 C++ 部分模板专业化问题的主要内容,如果未能解决你的问题,请参考以下文章

gcc 4.5.1 与 VC2010 模板部分专业化:哪个符合 C++0x?

C++ 部分模板专业化 - 设计简化

模板专业化,Windows 与 gcc 上的不同行为?

使用 STL 容器的部分 C++ 模板特化

这是为成员函数的 C++ 模板部分特化构造类的好方法吗?

指针的 C++ 模板特化?