動作させることはできますが、考慮する必要があることがいくつかあります。
vals
は、型のないパラメータとして渡すことができます。しかし、それはT
の後に来る必要があります。それ以外の場合は、パラメータの基本型はわかりません。
したがって、デフォルト値のT
はありません。 T
のデフォルト値はdouble
で、最後の引き数のデフォルト値はnullptr
ですが、それは乱雑なコードにつながります。
id_3by3
の定義は、vals
ではなく、&vals
を使用する必要があります。
をconst
と定義した場合、非タイプのテンプレートパラメータでもそのタイプにconst
を使用する必要があります。あなたは行列の内容を変更できるようにしたい場合は、
template <std::size_t r, std::size_t c, class T, T const(*v)[r][c] >
class abstract_matrix { ... };
を使用
const int vals[3][3] { ... };
任務は、あなたが使用する必要があります:あなたが使用することを義務付け
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のcommment
に応じて、あなたが使用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>;
これは、これらの行を2つの.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:あなたが必要とすることなく、異なる.hファイルにid_3by3
に類似した他のタイプを定義することができます
#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>;
それらのすべてにabstract_matrix
の定義を複製します。
行列の値をその型の一部にしたいですか?どうして?なぜ単純に 'abstract_matrix <3, 3, int> id_3by3(vals);'? – Thomas
テンプレートの引数リストに 'vals'を渡したくありません。 'std :: initializer_list'を見てください。彼らは潜在的に修正されているものの、 'constexpr'にいくつかの問題を提示します。 https://stackoverflow.com/questions/15937522/constexpr-array-and-stdinitializer-listを参照してください。 –
はい、実際に要素の値を型の一部にしたくないのですが、それは素早く想像することのできない膨大な数のテンプレートの膨張につながります。特定の次元を超えておそらくあなたはなぜあなたがこれを望んでいると思うのかを説明してください。そうすれば、あなたはそれをしないより有用な答えを得ることができます。 –