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

回答編集履歴

3

参考例のコードを追加

2021/05/13 13:52

投稿

SaitoAtsushi
SaitoAtsushi

スコア5741

answer CHANGED
@@ -8,4 +8,57 @@
8
8
 
9
9
  無いです。 .cpp の中に記述したらそのファイル内でしか使えません。
10
10
 
11
- 古い仕様ではオプショナルな仕様として `export` キーワードがありましたが、実装した処理系がごく一部しかなかったこともあって C++11 で完全に廃止されました。
11
+ 古い仕様ではオプショナルな仕様として `export` キーワードがありましたが、実装した処理系がごく一部しかなかったこともあって C++11 で完全に廃止されました。
12
+
13
+ # 参考例
14
+
15
+ 肝心なことは
16
+
17
+ - 配列大きさは型の一部。 この場合は省略できない。
18
+ - メンバ関数の部分特殊化はできない。 補助的なクラステンプレートを作って部分特殊化をするのが典型的な方法。
19
+
20
+ です。
21
+
22
+ mbed の開発環境を用意していないのでとりあえず雰囲気だけですが、型によって呼び分ける例を書いてみました。 与えられる型によって呼び分けられていることはわかると思います。
23
+
24
+ ```cpp
25
+ #include <iostream>
26
+
27
+ class serial_writer {
28
+ private:
29
+ template<class T, std::size_t N>
30
+ struct helper {
31
+ static void write(T (&send)[N]) {
32
+ std::cout << "write(generic version)" << std::endl;
33
+ }
34
+ };
35
+ template<std::size_t N>
36
+ struct helper<double, N> {
37
+ static void write(double (&send)[N]) {
38
+ std::cout << "write(double version)" << std::endl;
39
+ }
40
+ };
41
+ template<std::size_t N>
42
+ struct helper<float, N> {
43
+ static void write(float (&send)[N]) {
44
+ std::cout << "write(float version)" << std::endl;
45
+ }
46
+ };
47
+
48
+ public:
49
+ template<class T, std::size_t N> void write(T (&send)[N]) {
50
+ helper<T, N>::write(send);
51
+ }
52
+ };
53
+
54
+ int main(void) {
55
+ int foo[10];
56
+ double bar[20];
57
+ float baz[30];
58
+
59
+ serial_writer writer;
60
+ writer.write(foo);
61
+ writer.write(bar);
62
+ writer.write(baz);
63
+ }
64
+ ```

2

ポインタではなく配列に置き換え

2021/05/13 13:52

投稿

SaitoAtsushi
SaitoAtsushi

スコア5741

answer CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  テンプレートの内部では Two-phase name lookup という仕組みが働きます。 定義時点でその名前が意味するところが確定しているものは解決しますがそうでないものはわかるまで後回しにするという仕組みです。 テンプレートの定義時点でエラーであることがわかるものもありますが、使われてはじめてエラーになることもあります。
4
4
 
5
- `T` が何者であるかというのはこの `write` が使われるまでわかりません。 ポインタが渡されれば問題なく実体化できる可能性があるからこの時点ではエラーになりませんが、ポインタでないものが渡されればエラーになるでしょう。 そして特殊化したほうについては使われるのを待たずともそれが間違っていることが確定しています。
5
+ `T` が何者であるかというのはこの `write` が使われるまでわかりません。 配列が渡されれば問題なく実体化できる可能性があるからこの時点ではエラーになりませんが、配列でないものが渡されればエラーになるでしょう。 そして特殊化したほうについては使われるのを待たずともそれが間違っていることが確定しています。
6
6
 
7
7
  > templateを.hファイルでなくて.cppファイルに記述する方法
8
8
 

1

ポインタではなく配列を意図したコードになっているようなので修正

2021/05/13 11:06

投稿

SaitoAtsushi
SaitoAtsushi

スコア5741

answer CHANGED
@@ -1,4 +1,4 @@
1
- `send` が `double` 型だからです。 インデクスを付けることはできません。 `double*` を意図していたのでしょうか? 単純ミスですね。
1
+ `send` が `double` 型だからです。 インデクスを付けることはできません。 `double[]` (`double` の配列) を意図していたのでしょうか? 単純ミスですね。
2
2
 
3
3
  テンプレートの内部では Two-phase name lookup という仕組みが働きます。 定義時点でその名前が意味するところが確定しているものは解決しますがそうでないものはわかるまで後回しにするという仕組みです。 テンプレートの定義時点でエラーであることがわかるものもありますが、使われてはじめてエラーになることもあります。
4
4