【问题标题】:passing a templated class with constants as an argument传递带有常量作为参数的模板类
【发布时间】:2014-09-12 19:47:55
【问题描述】:

我的模板类如下所示:

template<unsigned WIDTH, unsigned HEIGTH, typename T = int> class matrix { ... }

如此简单明了,模板参数决定了矩阵的大小。大小在逻辑上是恒定的,所以我实现它是恒定的。但是当我尝试编写一个接受我的matrix 的函数时,我遇到了以下问题:

std::ostream& operator<<(std::ostream &os, const matrix &m){ ...}

这样写,编译器理所当然地反对缺少模板参数......但是

std::ostream& operator<<(std::ostream &os, const matrix<unsigned, unsigned> &m){ ...}

触发此错误:error: expected a constant of type 'unsigned int', got 'unsigned&gt; int'

这也是正确的,因为matrix 需要常量,而不是类型。

如何处理?我确定我不是第一个遇到这个问题的人,解决传递常量参数化模板这个问题的最“规范”方法是什么?

【问题讨论】:

  • 重载的operator&lt;&lt;也需要是模板。

标签: c++ templates constants compile-time-constant


【解决方案1】:

将模板类matrixoperator&lt;&lt;(ostream&amp;) 重载声明为模板,这应该是这里明显的解决方案

template<unsigned WIDTH, unsigned HEIGTH, typename T = int> 
class matrix 
{ 
public:
    T arr[WIDTH][HEIGTH];
};
template<unsigned WIDTH, unsigned HEIGTH, typename T>
std::ostream& operator<<(std::ostream &os, const matrix<WIDTH, HEIGTH,T> &m)
{ 
    // formatting inserter of m  onto os
    return os;
}

int main()
{
    matrix<10, 10> m;
    std::cout << m << std::endl;
}

但一般来说,如果您的 operator&lt;&lt;(ostream&amp;) 需要访问您的私人数据(通常会),您最终会将其声明为朋友。如果不想重复 remplate 参数,请将 operator&lt;&lt;(ostream&amp;) 非成员朋友放在矩阵类的范围内

template<unsigned WIDTH, unsigned HEIGTH, typename T = int> 
class matrix 
{ 
     T arr[WIDTH][HEIGTH];
     friend std::ostream& operator<<(std::ostream &os, const matrix &m)
     { 
         // formatting inserter of m  onto os
         return os;
     }
};

【讨论】:

  • 至少你在 HEIGTH 拼写错误方面相当一致:p(投票赞成)
  • @CarloWood:实际上,我从 OP 复制了它,但从未注意到它的拼写错误。无论如何,我都会让它与 OPs 问题保持同步:-)
【解决方案2】:

选项 #1

operator&lt;&lt; 声明为matrix 类范围内的朋友 函数:

template<unsigned WIDTH, unsigned HEIGTH, typename T = int>
class matrix
{
    friend std::ostream& operator<<(std::ostream &os, const matrix& m)
    //                                                      ^^^^^^ plain name
    {
        return os;
    }
};

选项 #2

也将operator&lt;&lt; 设为函数模板:

template<unsigned WIDTH, unsigned HEIGHT, typename T>
std::ostream& operator<<(std::ostream &os, const matrix<WIDTH, HEIGHT, T>& m)
//                                                      ^^^^^  ^^^^^^  ^
{
    return os;
}

【讨论】:

    【解决方案3】:

    重载的operator&lt;&lt; 也需要是模板:

    template<unsigned WIDTH, unsigned HEIGHT, typename T>
    std::ostream& operator<<(std::ostream &os, const matrix<WIDTH, HEIGHT, T> &m){
      // ...
      return os;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 2016-05-03
      相关资源
      最近更新 更多