回答編集履歴

1

C++11 で出来そうなことを追記

2024/04/26 10:53

投稿

SaitoAtsushi
SaitoAtsushi

スコア5466

test CHANGED
@@ -28,3 +28,46 @@
28
28
  }
29
29
  ```
30
30
 
31
+ # 追記。 C++11 でやれること
32
+
33
+ C++11 でも出来る範囲で最も簡単なのはクラステンプレートに渡すテンプレート引数を関数ポインタの型そのままで渡すことだと思います。
34
+
35
+ まとめて渡された型を内部の補助的なテンプレート経由の型推論で分離して必要な関数を構築するという手順を取れば型を渡すときには可変長にする必要がありません。
36
+
37
+ ```cpp
38
+ #include <iostream>
39
+ #include <type_traits>
40
+ #include <utility>
41
+
42
+ template <class MethodType,
43
+ MethodType Method,
44
+ class = typename std::enable_if<std::is_member_function_pointer<MethodType>::value, void*>::type>
45
+ class XXX {
46
+ template <class T, class ReturnType, class... Args>
47
+ struct helper {
48
+ static ReturnType CallTheMethod(T& t, Args... args) {
49
+ return (t.*Method)(args...);
50
+ }
51
+ };
52
+ template <class T, class ReturnType, class... Args>
53
+ static constexpr helper<T, ReturnType, Args...> deduce(ReturnType (T::*)(Args...)) {
54
+ return helper<T, ReturnType, Args...>();
55
+ }
56
+
57
+ public:
58
+ static constexpr auto CallTheMethod = decltype(deduce(Method))::CallTheMethod;
59
+ };
60
+
61
+ struct Test {
62
+ void F(int i, int j) {
63
+ std::cout << i << " " << j << "\n";
64
+ }
65
+ };
66
+
67
+ int main(void) {
68
+ Test t;
69
+ XXX<void (Test::*)(int, int), &Test::F> xxx;
70
+ xxx.CallTheMethod(t, 33, 44);
71
+ }
72
+ ```
73
+