質問するログイン新規登録

回答編集履歴

4

修正

2021/05/27 00:18

投稿

asm
asm

スコア15149

answer CHANGED
@@ -20,6 +20,7 @@
20
20
 
21
21
  template<typename T, size_t Dim, typename... Args>
22
22
  NPtr<T, Dim>::type AllocDim(Args... _width){
23
+ static_assert(Dim == sizeof...(_width), "sizeof...(_width) must equal Dim");
23
24
  std::array<size_t, Dim> width = {_width...};
24
25
  size_t elements = 1, points = 0;
25
26
  for(size_t i = 0; i < Dim; i++) {

3

修正

2021/05/27 00:18

投稿

asm
asm

スコア15149

answer CHANGED
@@ -2,10 +2,12 @@
2
2
  ご質問のように仮引数によって動的に型を決定する事はできません。
3
3
 
4
4
  ---
5
- C++においてはテンプレートによって作れそうな気はし
5
+ C++においてはテンプレートによって作れました。
6
6
  が、前述のようにコンパイル時に`Dim`が決定されている必要があったりと実用的かは微妙です
7
7
 
8
8
  ```c++
9
+ #include <array>
10
+
9
11
  template <typename T, size_t Dim>
10
12
  struct NPtr{
11
13
  typedef NPtr<T,Dim-1>::type* type;
@@ -16,8 +18,9 @@
16
18
  typedef T type;
17
19
  };
18
20
 
19
- template<typename T, size_t Dim>
21
+ template<typename T, size_t Dim, typename... Args>
20
- NPtr<T, Dim>::type AllocDim(size_t width[Dim]){
22
+ NPtr<T, Dim>::type AllocDim(Args... _width){
23
+ std::array<size_t, Dim> width = {_width...};
21
24
  size_t elements = 1, points = 0;
22
25
  for(size_t i = 0; i < Dim; i++) {
23
26
  points += elements;
@@ -41,10 +44,14 @@
41
44
  *it++ = (void*)(base + memo + l * diff);
42
45
  }
43
46
  }
47
+ size_t last = width[Dim-1];
44
48
  for(size_t i = 0; it < (void**)data; i++) {
45
- *it++ = (void*)(data + i * sizeof(T));
49
+ *it++ = (void*)(data + last * i * sizeof(T));
46
50
  }
47
51
  return (typename NPtr<T, Dim>::type) result;
48
52
  }
49
53
 
54
+ int main(){
55
+ char*** ptr = AllocDim<char, 3>(3,2,2);
56
+ }
50
57
  ```

2

修正

2021/05/27 00:03

投稿

asm
asm

スコア15149

answer CHANGED
@@ -6,7 +6,6 @@
6
6
  が、前述のようにコンパイル時に`Dim`が決定されている必要があったりと実用的かは微妙です
7
7
 
8
8
  ```c++
9
- // 作りかけ
10
9
  template <typename T, size_t Dim>
11
10
  struct NPtr{
12
11
  typedef NPtr<T,Dim-1>::type* type;
@@ -25,18 +24,27 @@
25
24
  elements *= width[i];
26
25
  }
27
26
  points -= 1;
28
-
29
- void* result = malloc(elements * sizeof(T) + points * sizeof(void*));
27
+ size_t size = elements * sizeof(T) + points * sizeof(void**);
28
+ void* result = malloc(size);
30
29
  if(!result)
31
- return result;
30
+ return nullptr;
32
31
  void** it = (void**)result;
33
32
  char* data = (char*)(it+points);
33
+ size_t memo = 0;
34
+ size_t t = 1;
34
- for(size_t i = 0; i < Dim-1; i++) {
35
+ for(size_t i = 0; i < Dim-2; i++) {
36
+ size_t w = width[i], diff = width[i+1];
37
+ memo += w;
38
+ t *= w;
35
- // ここと
39
+ void** base = it;
40
+ for(size_t l = 0; l < t; l++) {
41
+ *it++ = (void*)(base + memo + l * diff);
42
+ }
36
43
  }
37
- for(size_t i = 0; i < width[Dim-1]; i++) {
44
+ for(size_t i = 0; it < (void**)data; i++) {
38
- // ここ
45
+ *it++ = (void*)(data + i * sizeof(T));
39
46
  }
40
47
  return (typename NPtr<T, Dim>::type) result;
41
48
  }
49
+
42
50
  ```

1

修正

2021/05/26 23:26

投稿

asm
asm

スコア15149

answer CHANGED
@@ -37,6 +37,6 @@
37
37
  for(size_t i = 0; i < width[Dim-1]; i++) {
38
38
  // ここ
39
39
  }
40
- return (NPtr<T, Dim>::type) result;
40
+ return (typename NPtr<T, Dim>::type) result;
41
41
  }
42
42
  ```