【问题标题】:C++ template specialization for specific values特定值的 C++ 模板特化
【发布时间】:2013-06-02 13:46:57
【问题描述】:

我有 struct Opers 和一些算术运算:mult()div()mod()

我需要专门针对n 的某些值的模板。这是Opers<1> 的示例。

但是,我还想对 n 进行专门化,即 2 的幂(n = 2,4,8,16, ...)——在这种情况下,我可以优化操作 mult()div() (使用左移或右移)。

#include <iostream>
using namespace std;
template<int n> struct Opers {
    int mult(int x){
        return n*x;
    }
    int div(int x){
        return x / n;
    }   
    int mod(int x){
        return x % n;
    }   
};
template<> struct Opers<1> {
    int mult(int x){
        return 1;
    }
    int div(int x){
        return x;
    }   
    int mod(int x){
        return 0;
    }           
};
int main() {
    Opers<1> el2;
    cout << el2.mult(3) <<endl;
} 

我正在寻找类似的建筑

template<> struct Opers<isPowerOfTwo()>
    int mult(int x){
        // do smth
     }

有没有可能,或者我应该阅读什么手册?

UPD。允许使用 C++11,甚至会更好。

【问题讨论】:

  • 啊...通过使用班次进行优化。编译器会说,“哇,我从来没有想到过”......
  • 我知道编译器没关系!这只是一个示例(与我的学习任务相关),我找不到正确的代码结构或方法......

标签: c++ templates c++11 template-specialization partial-specialization


【解决方案1】:

在 C++11 中,您可以这样做。首先,更改您的主模板,使其接受第二个虚拟参数:

template<int n, typename = void>
struct Opers 
{
    // ...
};

然后,写一个constexpr函数,判断一个整数是否是2的幂:

constexpr bool is_power_of_two(int x)
{
    return (x == 1) || ((x % 2 == 0) && is_power_of_two(x / 2));
}

最后,使用 SFINAE 根据您的constexpr 函数的结果启用或禁用专业化:

#include <type_traits>

template<int n>
struct Opers<n, typename std::enable_if<is_power_of_two(n)>::type>
{
    // ...
};

【讨论】:

  • x &amp; (x - 1) == 0不会检查同样的东西吗?
  • @soon:也许,是的,但我发现我的版本更容易理解。此外,这是在编译时完成的,因此性能不太可能成为问题
  • template&lt;int n, bool ispow2 = is_power_of_two(n)&gt; 呢?
  • @DyP:这也是一种可能性,但我认为我的解决方案更通用,因为它允许在不更改主模板的情况下添加新的专业化
  • 非常感谢!这正是我想要的!
【解决方案2】:
template <int N, typename = void>
struct Operations
{
    // ....
};

template <int N, typename = std::enable_if<(N & (N - 1))>::type>
struct Operations
{
    // ....
};

【讨论】:

    猜你喜欢
    • 2022-07-05
    • 1970-01-01
    • 2023-04-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多