【问题标题】:C++ partial template specialization issue with gccgcc 的 C++ 部分模板专业化问题
【发布时间】: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 函数。
  • 你的数学在这里不行。

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


【解决方案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++ 两者都实现。

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多