ホームページ > バックエンド開発 > C++ > C テンプレートのメタプログラミングはチューリング完全ですか?

C テンプレートのメタプログラミングはチューリング完全ですか?

Mary-Kate Olsen
リリース: 2024-11-23 10:25:11
オリジナル
312 人が閲覧しました

Is C   Template Metaprogramming Turing-Complete?

C テンプレートはチューリング完全ですか?

広く広まっている主張は、C テンプレートはコンパイル時にチューリング完全であるというものです。これは、テンプレートを使用して計算可能な関数を表現および実行できることを意味します。

計算の例

これは、C で実装されたチューリング マシンの重要な例です。 11 テンプレートの使用:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

#include <iostream>

 

template<bool C, typename A, typename B>

struct Conditional {

    typedef A type;

};

 

template<typename A, typename B>

struct Conditional<false, A, B> {

    typedef B type;

};

 

template<typename...>

struct ParameterPack;

 

template<bool C, typename = void>

struct EnableIf { };

 

template<typename Type>

struct EnableIf<true, Type> {

    typedef Type type;

};

 

template<typename T>

struct Identity {

    typedef T type;

};

 

// define a type list

template<typename...>

struct TypeList;

 

template<typename T, typename... TT>

struct TypeList<T, TT...>  {

    typedef T type;

    typedef TypeList<TT...> tail;

};

 

template<>

struct TypeList<>> {

 

};

 

template<typename List>

struct GetSize;

 

template<typename... Items>

struct GetSize<TypeList<Items...>> {

    enum { value = sizeof...(Items) };

};

 

template<typename... T>

struct ConcatList;

 

template<typename... First, typename... Second, typename... Tail>

struct ConcatList<TypeList<First...>, TypeList<Second...>, Tail...> {

    typedef typename ConcatList<TypeList<First..., Second...>,

                                Tail...>::type type;

};

 

template<typename T>

struct ConcatList<T> {

    typedef T type;

};

 

template<typename NewItem, typename List>

struct AppendItem;

 

template<typename NewItem, typename...Items>

struct AppendItem<NewItem, TypeList<Items...>> {

    typedef TypeList<Items..., NewItem> type;

};

 

template<typename NewItem, typename List>

struct PrependItem;

 

template<typename NewItem, typename...Items>

struct PrependItem<NewItem, TypeList<Items...>> {

    typedef TypeList<NewItem, Items...> type;

};

 

template<typename List, int N, typename = void>

struct GetItem {

    static_assert(N > 0, "index cannot be negative");

    static_assert(GetSize<List>::value > 0, "index too high");

    typedef typename GetItem<typename List::tail, N-1>::type type;

};

 

template<typename List>

struct GetItem<List, 0> {

    static_assert(GetSize<List>::value > 0, "index too high");

    typedef typename List::type type;

};

 

template<typename List, template<typename, typename...> class Matcher, typename... Keys>

struct FindItem {

    static_assert(GetSize<List>::value > 0, "Could not match any item.");

    typedef typename List::type current_type;

    typedef typename Conditional<Matcher<current_type, Keys...>::value,

                                 Identity<current_type>,

                                 FindItem<typename List::tail, Matcher, Keys...>>

        ::type::type type;

};

 

template<typename List, int I, typename NewItem>

struct ReplaceItem {

    static_assert(I > 0, "index cannot be negative");

    static_assert(GetSize<List>::value > 0, "index too high");

    typedef typename PrependItem<typename List::type,

                             typename ReplaceItem<typename List::tail, I-1,

                                                  NewItem>::type>

        ::type type;

};

 

template<typename NewItem, typename Type, typename... T>

struct ReplaceItem<TypeList<Type, T...>, 0, NewItem> {

    typedef TypeList<NewItem, T...> type;

};

 

enum Direction {

    Left = -1,

    Right = 1

};

 

template<typename OldState, typename Input, typename NewState,

         typename Output, Direction Move>

struct Rule {

    typedef OldState old_state;

    typedef Input input;

    typedef NewState new_state;

    typedef Output output;

    static Direction const direction = Move;

};

 

template<typename A, typename B>

struct IsSame {

    enum { value = false };

};

 

template<typename A>

struct IsSame<A, A> {

    enum { value = true };

};

 

template<typename Input, typename State, int Position>

struct Configuration {

    typedef Input input;

    typedef State state;

    enum { position = Position };

};

 

template<int A, int B>

struct Max {

    enum { value = A > B ? A : B };

};

 

template<int n>

struct State {

    enum { value = n };

    static char const * name;

};

 

template<int n>

char const* State<n>::name = "unnamed";

 

struct QAccept {

    enum { value = -1 };

    static char const* name;

};

 

struct QReject {

    enum { value = -2 };

    static char const* name;

};

 

#define DEF_STATE(ID, NAME) \

    typedef State<ID> NAME ; \

    NAME :: name = #NAME ;

 

template<int n>

struct Input {

    enum { value = n };

    static char const * name;

 

    template<int... I>

    struct Generate {

        typedef TypeList<Input<I>...> type;

    };

};

 

template<int n>

char const* Input<n>::name = "unnamed";

 

typedef Input<-1> InputBlank;

 

#define DEF_INPUT(ID, NAME) \

    typedef Input<ID> NAME ; \

    NAME :: name = #NAME ;

 

template<typename Config, typename Transitions, typename = void>

struct Controller {

    typedef Config config;

    enum { position = config::position };

 

    typedef typename Conditional<

        static_cast<int>(GetSize<typename config::input>::value)

            <= static_cast<int>(position),

        AppendItem<InputBlank, typename config::input>,

        Identity<typename config::input>>::type::type input;

    typedef typename config::state state;

 

    typedef typename GetItem<input, position>::type cell;

 

    template<typename Item, typename State, typename Cell>

    struct Matcher {

        typedef typename Item::old_state checking_state;

        typedef typename Item::input checking_input;

        enum { value = IsSame<State, checking_state>::value &amp;&amp;

                       IsSame<Cell,  checking_input>::value

        };

    };

    typedef typename FindItem<Transitions, Matcher, state, cell>::type rule;

 

    typedef typename ReplaceItem<input, position, typename rule::output>::type new_input;

    typedef typename rule::new_state new_state;

    typedef Configuration<new_input,

                          new_state,

                          Max<position + rule::direction, 0>::value> new_config;

 

    typedef Controller<new_config, Transitions> next_step;

    typedef typename next_step::end_config end_config;

    typedef typename next_step::end_input end_input;

    typedef typename next_step::end_state end_state;

    enum { end_position = next_step::position };

};

 

template<typename Input, typename State, int Position, typename Transitions>

struct Controller<Configuration<Input, State, Position>, Transitions,

                  typename EnableIf<IsSame<State, QAccept>::value ||

                                    IsSame<State, QReject>::value>::type> {

    typedef Configuration<Input, State, Position> config;

    enum { position = config::position };

    typedef typename Conditional<

        static_cast<int>(GetSize<typename config::input>::value)

            <= static_cast<int>(position),

        AppendItem<InputBlank, typename config::input>,

        Identity<typename config::input>>::type::type input;

    typedef typename config::state state;

 

    typedef config end_config;

    typedef input end_input;

    typedef state end_state;

    enum { end_position = position };

};

 

template<typename Input, typename Transitions, typename StartState>

struct TuringMachine {

    typedef Input input;

    typedef Transitions transitions;

    typedef StartState start_state;

ログイン後にコピー

以上がC テンプレートのメタプログラミングはチューリング完全ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート