繁体   English   中英

编译时矩阵模板类型

[英]Compile-time matrix template type

我正在尝试获得一段我编写的代码,以实现有趣的工作。 基本上,我想生成一个在编译时给定的类型 :一个矩阵。

例如,我希望abstract_matrix如下所示:

template <std::size_t r, std::size_t c, class T = double>
class abstract_matrix
{
public:

    static const std::size_t rows = r;

    static const std::size_t cols = c;

    typedef T value_type;

    typedef T storage_type[rows][cols];

    constexpr abstract_matrix(storage_type items)
    {
        // I hope it's not needed
    }

    storage_type storage;
};

然后,我想按照以下方式实际创建带有魔术的具体类型:

constexpr static const int vals[3][3] {
    { 1, 0, 0 },
    { 0, 1, 0 },
    { 0, 0, 1 }
};

// do magic here for the vals parameter to make this compile
using id_3by3 = abstract_matrix<3, 3, vals, int>;

// use the generated type
id_3by3 mymatrix;

auto matrix = mymatrix * ...;

您对如何在编译时这些值“ 注入 ”模板并生成适当的类型有任何建议吗? 该类型中的所有内容都是staticconstconstexpr

谢谢!

您可以使其工作,但必须考虑一些事项。

  1. vals可以作为非类型参数传递。 但是,它必须在T之后。 否则,参数的基本类型未知。

    结果,没有默认值T 您可能会继续将T默认值设为double ,将最后一个参数的默认值设为nullptr但这会导致代码混乱。

  2. id_3by3定义需要使用&vals ,而不仅仅是vals

  3. 如果将vals定义为const ,则非类型模板参数还必须在其类型中使用const

     const int vals[3][3] { ... }; 

    您使用的命令

     template <std::size_t r, std::size_t c, class T, T const(*v)[r][c] > class abstract_matrix { ... }; 

    如果您希望能够修改矩阵的内容,则需要使用:

     template <std::size_t r, std::size_t c, class T, T (*v)[r][c]> class abstract_matrix { ... }; 

    您使用哪个指令

     int vals[3][3] { ... }; 

这是一个工作程序:

#include <iostream>
#include <cstdint>

template <std::size_t r, std::size_t c, class T , T (*v)[r][c]>
class abstract_matrix
{
public:

    static const std::size_t rows = r;

    static const std::size_t cols = c;

    typedef T value_type;

    constexpr static T(&vals)[r][c] = *v;

    constexpr abstract_matrix()
    {
    }
};

int vals[3][3] {
    { 1, 0, 0 },
    { 0, 1, 0 },
    { 0, 0, 1 }
};

using id_3by3 = abstract_matrix<3, 3, int, &vals>;

int main()
{
   id_3by3 mymatrix;

   // Original matrix.
   for ( size_t i = 0; i < id_3by3::rows; ++i )
   {
      for ( size_t j = 0; j < id_3by3::cols; ++j )
      {
         std::cout << id_3by3::vals[i][j] << " ";
         id_3by3::vals[i][j]++;
      }
      std::cout << "\n";
   }
   std::cout << "\n";

   // Modified matrix.
   for ( size_t i = 0; i < id_3by3::rows; ++i )
   {
      for ( size_t j = 0; j < id_3by3::cols; ++j )
      {
         std::cout << id_3by3::vals[i][j] << " ";
      }
      std::cout << "\n";
   }
}

输出:

1 0 0
0 1 0
0 0 1

2 1 1
1 2 1
1 1 2

更新,以回应OP的评价

您可以使用static int vals[3][3] = { ... }; 当您希望能够定义.h文件的类型并在多个.cpp文件中使用它时。

我可以在多个.cpp文件中使用具有以下内容的.h文件。

#pragma once
#include <cstdint>

template <std::size_t r, std::size_t c, class T , T (*v)[r][c]>
class abstract_matrix
{
   public:

      static const std::size_t rows = r;

      static const std::size_t cols = c;

      typedef T value_type;

      constexpr static T(&vals)[r][c] = *v;

      constexpr abstract_matrix()
      {
      }
};

static int vals[3][3] {
   { 1, 0, 0 },
   { 0, 1, 0 },
   { 0, 0, 1 }
};

using id_3by3 = abstract_matrix<3, 3, int, &vals>;

仍然可以通过将这些行分成两个.h文件来改进。 例如,您可以使用:

abstract_matrix.h:

#pragma once
#include <cstdint>

template <std::size_t r, std::size_t c, class T , T (*v)[r][c]>
class abstract_matrix
{
   public:

      static const std::size_t rows = r;

      static const std::size_t cols = c;

      typedef T value_type;

      constexpr static T(&vals)[r][c] = *v;

      constexpr abstract_matrix()
      {
      }
};

id_3by3.h:

#include "abstract_matrix.h"

static int vals[3][3] {
   { 1, 0, 0 },
   { 0, 1, 0 },
   { 0, 0, 1 }
};

using id_3by3 = abstract_matrix<3, 3, int, &vals>;

这样一来,您就可以在不同的.h文件中定义其他类似于id_3by3类型,而无需在所有文件中重复abstract_matrix的定义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM