forked from EzoeRyou/cpp-book
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathC++11-Syntax-and-Feature.xhtml
32441 lines (25637 loc) · 930 KB
/
C++11-Syntax-and-Feature.xhtml
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
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html >
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>
C++11: Syntax and Feature
</title>
<style type="text/css">
<![CDATA[
body
{
background-color : #efefef ;
margin-left : 1em ;
font-size : large ;
}
p
{
}
h1, h2, h3, h4, h5, h6
{
font-size : x-large ;
font-weight : normal ;
}
div#content pre
{
display : block ;
font-family: "Inconsolata", "Consolas", monospace ;
border-style: solid ;
border-width: medium ;
border-color: black ;
padding: 0em 1em 1em 1em ;
background-color: #ffffdd ;
word-wrap: break-word ;
white-space : pre-wrap ;
border-radius: 0.4em ;
}
/*
* i element represents represents syntactic categories.
* b element represents other technical terms.
* as defined in HTML5 draft.
*/
i, b
{
font-weight : normal ;
font-style : normal ;
text-decoration : none ;
}
#index > li
{
margin-bottom : 1em ;
}
a
{
text-decoration : none ;
}
a:hover
{
background-color : #ffffdd ;
border-radius: 0.4em ;
-moz-border-radius: 0.4em ;
-webkit-border-radius: 0.4em ;
}
.maybe
{
background-color : #dfdfdf ;
border-radius: 0.4em ;
-moz-border-radius: 0.4em ;
-webkit-border-radius: 0.4em ;
}
.maybe a
{
color : black ;
}
.maybe > a:before
{
content : "[書かないかも] " ;
}
.hide
{
background-color : #dfdfdf ;
border-radius: 0.4em ;
}
.hide a
{
color : black ;
}
.hide > a:before
{
content : "[ネストが深すぎる] " ;
}
.editorial-note
{
padding : 1em ;
border : red thick solid ;
}
article
{
display : block ;
margin-bottom : 4em ;
}
#content > article.toplevel
{
display : block ;
}
section
{
display : block ;
padding-left : 2em ;
}
.todo
{
padding : 1em ;
border : red thick solid ;
}
.todo:before
{
content : "TODO: " ;
}
table
{
border-collapse:collapse;
}
table, th, td
{
padding : 0.5em ;
border : black thin solid ;
}
]]>
</style>
<script type="application/javascript" >
<![CDATA[
"use strict" ;
// helper functions
// calculate nth <li> child element from parent node.
function calculate_nth_child_element(element)
{
var n = 1 ;
var iter = element.parentNode.firstElementChild ;
while (!iter.isSameNode(element))
{
++n ;
iter = iter.nextElementSibling ;
}
return n ;
}
// generate chapter numbers for a given li element.
function generate_chapter_numbers( li )
{
var number = calculate_nth_child_element( li ) ;
// parent node shall be an ul element.
var parent = li.parentNode ;
// if ul's parent element's id attribute is "index"
if ( parent.parentNode.getAttribute( "id" ) == "index" )
{ // we reached the top of the index list.
return number ;
}
else
{ // continues to the upper chapter.
/// parent.parentNode shall be an li element.
return generate_chapter_numbers( parent.parentNode ) + "." + number ;
}
}
// add chapter numbers to all anchor elements.
function add_chapter_numbers()
{
var content = document.getElementById("content") ;
var index = document.getElementById("index") ;
var anchor_list = document.getElementsByTagName("a") ;
// itarete through each anchor element to insert the corresponding chapter numbers.
for (var i = 0 ; i != anchor_list.length ; ++i)
{
var node = anchor_list.item(i) ;
var href = node.getAttribute("href") ;
var selector = 'a[href="' + href + '"]' ;
var query = index.querySelector(selector) ;
if ( query == null )
{
continue ;
}
var li = query.parentNode ;
if (li == null)
continue ;
var chapter_numbers = generate_chapter_numbers(li) ;
node.parentNode.insertBefore( document.createTextNode(chapter_numbers + " "), node ) ;
}
}
// recursively construct the index.
function generate_nested_index( parent, element, selector )
{
var list = element.querySelectorAll( selector ) ;
if ( list.length == 0 )
return ;
var ul = document.createElement("ul") ;
parent.appendChild( ul ) ;
for ( var i = 0 ; i != list.length ; ++i )
{
var elem = list.item(i) ;
var heading = elem.firstElementChild ; // must be heading element
/*
var pattern = /h[1-6]/ ;
if ( heading == null ||
pattern.test(heading.nodeName) == false ||
// workaround
heading.firstElementChild == null
)
{
continue ;
}
*/
var li = document.createElement("li") ;
li.appendChild( heading.firstElementChild.cloneNode( true ) ) ;
ul.appendChild( li ) ;
generate_nested_index( li, elem, selector + " > article" ) ;
}
}
// construct a index from content's DOM.
function generate_index()
{
var index = document.getElementById("index") ;
var content = document.getElementById("content") ;
generate_nested_index( index, content, "#content > article" ) ;
}
function listener()
{
generate_index() ;
add_chapter_numbers() ;
}
window.addEventListener("load", listener, false ) ;
]]>
</script>
</head>
<body>
<h1>C++11の文法と機能(C++11: Syntax and Feature)</h1>
<pre>
Copyright (C) 2013 江添亮.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
</pre>
<p>
筆者について
</p>
<p>
名前:江添亮<br />
Mail : [email protected]<br />
Blog : <a href="http://cpplover.blogspot.jp/">http://cpplover.blogspot.jp/</a><br />
GitHub: <a href="https://github.com/EzoeRyou/cpp-book">https://github.com/EzoeRyou/cpp-book</a>
</p>
<h1>序</h1>
<p>
本書はC++11のコア言語の文法と機能を、標準規格書に従って解説したものである。正式なC++規格書として発行された後の、ひとつ後のドラフト規格、<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf">N3337
</a>を参考にしている。ドラフト規格を参考にした理由は、正式なC++規格書は、個人での入手が煩わしいためである。読者に入手が困難な資料を元に記述された参考書は価値がない。そのため、読者が容易に入手できるドラフト規格のうち、正式なC++規格書とほとんどかわらないN3337を参考にした。
</p>
<p>
本書の対象読者は、C++を記述するものである。C++実装者ではない。そのため、サンプルコードを増やし、冗長な解説を増やし、C++コンパイラーを実装するための詳細な定義は省いた。そもそも本書はC++規格の翻訳ではなく、C++規格の検証に使うことはできない。
</p>
<p>
本書の執筆は、まだC++11がC++0xと呼ばれていた2010年から始まっている。そのため、当時のドラフト規格を参考に書かれた部分もあり、正式なC++11規格とは異なっている可能性がある。また、正式に発行されたC++11規格には不具合も多数見つかっているため、C++14では異なっている部分もある。また、ドラフトの時点であまりにも変更が激しい箇所は飛ばしたので、漏れもある。
</p>
<p>
このような未完成品を公開するのは忍びないが、且は執筆資金枯渇のため、且は執筆環境消失のため、今公開することにした。
</p>
<p>
本書はC++11を解説する目的で書き始めたが、C++11の正式規格には様々な不具合が見つかり、誤りを正すために、マイナーアップデートなるC++14の制定が2014年に予定されている。また、その次の2017年には、メジャーアップデートとなるC++17が控えている。C++14はアップデートとはいえ、文面的にかなり大きな変更を含むため、もともとC++0xドラフトによって書かれ、C++11規格を参考にした本書の小手先の修正では対応できない。
</p>
<p>
本書の執筆は2010年から始まっているが、C++14が真剣に議論されだした2012年から、執筆が滞りがちになった。
</p>
<p>
筆者は常に最新のC++ドラフトを参照しているが、本書はC++11の参考書であるし、また、まだ不安定なドラフト規格の文面を参考にすることはできない。結果として、本書の執筆には、普段参照している最新のC++ドラフトからは、はるかに遅れたC++11規格を参照しなければならず、執筆の妨げとなった。
</p>
<p>
また、本書を記述するHTML/CSS/JavaScriptも、何年も前の未熟な理解により、甚だ稚拙であり、編集の妨げとなった。
</p>
<p>
この問題を解決するには、フルスクラッチからの書き直しが必要になるが、それはすでに費やした労力を捨て去ることになり、やはり意味がない。
</p>
<p>
あるいはこれ、伽藍とバザールの典型例かもしれず、早期に公開していれば、今とは違った結果になったかもしれない。
</p>
<p>
筆者は、プログラミングの参考書は、自由であるべきだと信じており、この参考書は、自由を保証するコピーレフトなライセンスで公開する。
</p>
<p>
2013年10月26日<br />
江添亮
</p>
<div id="index">
</div>
<div id="content">
<article class="toplevel">
<h1 id="intro"><a href="#intro">概要(General)</a></h1>
<article>
<h1 id="what-is-Cpp"><a href="#what-is-Cpp">C++とは</a></h1>
<p>
TODO:C++に関する一般的な説明
</p>
</article>
<article>
<h1 id="intro.defs"><a href="#intro.defs">用語(Definitions)</a></h1>
<article>
<h1 id="intro.defs.argument.and.parameter"><a href="#intro.defs.argument.and.parameter">実引数(argument)と、仮引数(parameter)</a></h1>
<p>
引数には、ふたつの種類がある。実引数とは、関数やマクロ、throw文、テンプレートに、実際に渡す引数のことをいう。仮引数とは、関数宣言や関数の定義、例外ハンドラーのcatch句、マクロ、テンプレート仮引数のことをいう。たとえば、関数の場合、
</p>
<pre>
// xは仮引数
void f( int x ) ;
int main()
{
// 0は実引数
f(0) ;
// argは実引数
int arg = 0 ;
f( arg ) ;
}
</pre>
<p>
このように、関数の宣言や定義などの引数を、仮引数といい、関数の呼び出しの際に指定する引数を、実引数という。仮引数と実引数は、厳密に区別される。
</p>
</article>
<article>
<h1 id="intro.defs.static.and.dynamic"><a href="#intro.defs.static.and.dynamic">静的な型(static type)と、動的な型(dynamic type)</a></h1>
<p>
静的な型とは、実行しなくても、その意味が分かる型のことである。動的な型は、実行しなければ、その意味が決定出来ない型のことである。
</p>
</article>
<article>
<h1 id="intro.defs.signature"><a href="#intro.defs.signature">シグネチャー(signature)</a></h1>
<p>
シグネチャーとは、ある関数に対する、その関数の名前、引数のリストの型、戻り値の型、テンプレート仮引数のことである。また、メンバー関数の場合は、そのクラスや、CV修飾、リファレンス修飾も含まれる。また、その関数の属する名前空間も含まれる。シグネチャーは、その関数を特定するために用いられる。
</p>
</article>
<article>
<h1 id="intro.defs.ill.well"><a href="#intro.defs.ill.well">ill-formedプログラムと、well-formedプログラム</a></h1>
<p>
well-formedプログラムとは、文法上正しいプログラムである。ill-formedプログラムとは、well-formedではないプログラム、すなわち、文法上、間違ったプログラムである。多くの実装では、ill-formedプログラムは、コンパイルエラーとなる。
</p>
</article>
<article>
<h1 id="intro.defs.conditionally"><a href="#intro.defs.conditionally">実装可能な機能(conditionally-supported)</a></h1>
<p>
実装可能な機能とは、規格上、実装してなくてもよい機能や動作のことである。
</p>
</article>
<article>
<h1 id="intro.defs.imple.defined"><a href="#intro.defs.imple.defined">実装定義の動作(implementation-defined behavior)</a></h1>
<p>
実装定義の動作とは、well-formedではあるが、その意味が、実装によって変わるということである。
</p>
</article>
<article>
<h1 id="intro.defs.undefined"><a href="#intro.defs.undefined">未定義の動作(undefined behavior)</a></h1>
<p>
未定義の動作とは、そのプログラムの意味が、規格上定義されていないということである。その動作は実装によって異なり、あるいはエラーとなるかもしれないし、あるいは問題なく結果が予測できる動作となるかもしれない。一般に、エラーとなる場合が多い。未定義の動作を含むプログラムを書く場合は、そのコードの意味が、目的の実行環境で、明確に定義されているかどうかを確認するべきである。
</p>
</article>
<article>
<h1 id="intro.defs.unspecified"><a href="#intro.defs.unspecified">未規定の動作(unspecified behavior)</a></h1>
<p>
未規定の動作も、具体的な意味が、実装によって異なると言う点で、未定義の動作と変わらない。ただし、未規定の動作は、規格上、推奨される動作が決められていることも多く、多くの実装で、エラーにならない、何らかの意味のあるコードになると言う点で、未定義の動作よりは、安全である。ただし、これも、目的の実行環境での意味がどうなるのかを、正しく把握しておく必要がある。
</p>
</article>
</article>
<article>
<h1 id="syntax"><a href="#syntax">文法記法(Syntax notation)</a></h1>
<p>
TODO:文法記法を用いるのはやめようかと考えている。分かりにくい。
</p>
<p>
本書では、言語の文法を記述するのに、規格に準じた文法記法を用いる。
</p>
<p>
個々の文法は、<i>文法カテゴリー</i>(syntactic category)として定義される。ある文法カテゴリーは、複数の文法カテゴリーや、具体的な文法を持つことができる。複数の文法カテゴリーは、改行で示される。
</p>
<pre>
<i>文法カテゴリー</i>:
<i>サブ文法カテゴリー</i> category
category
<i>サブ文法カテゴリー</i>:
Syntactic
</pre>
<p>
この例では、以下の二つの文法が定義されることになる。
</p>
<pre>
Syntactic category
category
</pre>
<p>
また、省略可能な文法カテゴリーは、「文法カテゴリー<sub>opt</sub>」と表記される。
</p>
<pre>
{ <i>式</i><sub>opt</sub> }
</pre>
<p>
この場合、式は書いても書かなくてもよい。
</p>
<p>
本書では、分かりやすさを重視するため、規格ほどの厳密な文法記法を用いることはない。文法カテゴリーは、常に日本語で表記される。
</p>
</article>
<article>
<h1 id="intro.memory"><a href="#intro.memory">C++メモリーモデル(The C++ memory model)</a></h1>
<p>
C++では、メモリー領域のことを、ストレージ(storage)と呼ぶ。ストレージの最小単位は、バイトである。1バイトが何ビットであるかは定められていないが、少なくとも、8ビット以上であることが保証されている。最低8ビットである理由は、UTF-8の、ひとつのコード単位を格納できるようにするためである。メモリーは、連続したバイト列で表される。すべてのバイトは、ユニークなアドレスを持つ。
</p>
</article>
<article>
<h1 id="intro.object"><a href="#intro.object">C++オブジェクトモデル(The C++ object model)</a></h1>
<p>
オブジェクトは、メモリー上に構築される。intやfloatといった基本型や、ユーザーが定義したクラスも、すべてオブジェクトとして構築される。ただし、関数は、オブジェクトではない。オブジェクトは、変数の定義や、newによって生成される。
</p>
<pre>
// int型のオブジェクト
int x ;
int * pointer = new int ;
// Fooクラス型のオブジェクト
class Foo { } ;
Foo foo ;
Foo * foo_pointer = new Foo ;
</pre>
<p>
オブジェクトは、型や、<a href="#basic.stc">ストレージの有効期間</a>、<a href="#basic.life">生存期間</a>を持つ。
</p>
</article>
<article>
<h1><a href="#intro.execution">プログラムの実行(Program execution)</a></h1>
<p>
TODO:
</p>
</article>
</article>
<article class="toplevel">
<h1 id="lex"><a href="#lex">字句規約(Lexical conventions)</a></h1>
<p>
ここでは、C++のソースコードを表現する文字について解説する。
</p>
<article>
<h1 id="lex.separate"><a href="#lex.separate">翻訳単位(Separate translation)</a></h1>
<p>
プログラムは、ソースファイルという単位に分割される。ソースファイルとは、プリプロセッサが実行された後のソースコードである。
</p>
</article>
<article>
<h1 id="lex.phases"><a href="#lex.phases">ソースファイルの変換(Phase of translation)</a></h1>
<p>
ソースファイルは、コンパイルにかけられる前に、変換される。この変換の詳しい定義は略すが、特に知っておくべき変換が、いくつかある。
</p>
<p>
基本ソース文字セットではない文字は、UCNに変換される。
</p>
<p>
変換前
</p>
<pre>
あ
</pre>
<p>
変換後
</p>
<pre>
\u3042
</pre>
<p>
TODO:行末バックスラッシュを説明するのはやめようかと思う。
</p>
<p>
行末の\(バックスラッシュ)と、それに続く改行は、取り除かれる。
</p>
<p>
変換前
</p>
<pre>
int \
value \
= 0 ;
</pre>
<p>
変換後
</p>
<pre>
int value = 0 ;
</pre>
<p>
この改行の除去のルールは、注意を要する。例えば、
</p>
<p>
変換前
</p>
<pre>
/\
/\
これはコメント
int va\
lue = 0 ;
</pre>
<p>
変換後
</p>
<pre>
//これはコメント
int value = 0 ;
</pre>
<p>
連続する文字列リテラルのトークンは、連結される。
</p>
<p>
変換前
</p>
<pre>
"aaa"
"bbb" ;
</pre>
<p>
変換後
</p>
<pre>
"aaabbb" ;
</pre>
</article>
<article>
<h1 id="lex.charset"><a href="#lex.charset">文字セット(Character sets)</a></h1>
<p>
C++は、ソースファイルの文字コードを定めていない。ソースファイル内の文字は、環境依存の文字コードで表現される。
</p>
<article>
<h1 id="basic-source-character-set"><a href="#basic-source-character-set">基本ソース文字セット</a></h1>
<p>
基本ソース文字セット(basic source character set)とは、ソースファイルで使うことができる文字のことである。印字可能な文字は、以下の通り。
</p>
<pre>
a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
_ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ! = , \ " '
</pre>
<p>
上記に加えて、スペース、水平タブ、垂直タブ、フォームフィード、改行も使うことができる。
</p>
<p>
たとえば、ASCIIでいえば、@(アットマーク)や`(グレイヴ・アクセント)のような文字は、使われていない。
</p>
</article>
<article>
<h1 id="universal-character-name"><a href="#universal-character-name">ユニバーサル文字名</a></h1>
<p>
ユニバーサル文字名(UCN:universal character name)とは、ISO/IEC 10646で定義されている文字コードのことである。この文字コードは、ユニバーサル文字セットと呼ばれている。また、厳密には同じではないが、俗に、Unicodeと呼ばれることもある。UnicodeはUnicodeで、別の規格があるのだが、実用上、どちらもコードポイントやエンコード方式に、差がないため、よく混同される。本書では、ユニバーサル文字セットや、UTFエンコードに関する解説は行わない。
</p>
<p>
Nを16進数の一文字とすると、\uNNNNは、UCSにおけるコードポイント、0000NNNNで表される文字という意味になり、\UNNNNNNNNは、NNNNNNNNで表される文字と同じ意味になる。
</p>
<p>
例:
</p>
<pre>
\u3042 あ
\u3043 い
\U00003044 う
</pre>
<p>
このユニバーサル文字名は、リテラルやエスケープシーケンスではなく、もっと根本的に、文字と同等に扱われる。つまり、対応するユニバーサル文字として認識される。ユニバーサル文字名は、ソースコードのあらゆる場所で使うことができる。ソースコードのある場所に、ユニバーサル文字名を記述した場合、その場所に、対応するユニバーサル文字を記述したのと、全く同じ扱いがなされる。
</p>
<p>
ただし、生文字列リテラルの中では、ユニバーサル文字名は使えない。サロゲートの範囲のコードポイント(0xD800–0xDFFF)を指定することはできない。文字列リテラルの中では、ユニバーサル文字は実装により自動的にエンコードされるので、サロゲートコードポイントを明示的に使う必要はない。もし文字としてサロゲートコードポイントを使う必要があるならば、エスケープシーケンス\xが使える。文字リテラルや文字列リテラルの中以外では、コントロール文字の範囲のコードポイント(0x00–0x1F と 0x7F–0x9F)と、基本ソース文字セットに該当するコードポイントを指定することはできない。
</p>
<pre>
R"(\u3042)" ; // ユニバーサル文字名ではなく、文字通りに解釈されることに注意
u8"\u00E3\u0081\u0082" ; // OK、u8"あ"と同じ
u"\ud842\udfb7" ; // エラー、サロゲートコードポイントを明示的に使うことはできない
u"\u00020bb7" ; // OK、u"𠮷"と同じ
int \u0041 = 0 ; // エラー、ここで基本ソース文字セットは使えない
int \u3042 = 0 ; // OK
</pre>
<p>
</p>
</article>
</article>
<article>
<h1 id="lex.token"><a href="#lex.token">トークン(Tokens)</a></h1>
<p>
TODO:これは本当に必要な項目だろうか。この項目で定義されている、ホワイトスペースは、どこかで言及しておかなければならないが。むしろ、この項目を、空白とすべきか。
</p>
</article>
<article>
<h1 id="lex.comment"><a href="#lex.comment">コメント(Comments)</a></h1>
<p>
コメントには、二種類ある。/* */で囲まれた、複数行にわたるコメントと、//から始まり行末までの、一行コメントである。
</p>
<pre>
/* ここからコメント開始
これはコメント
これもコメント
ここでコメント終わり*/
// これは一行コメント。改行までがコメントとなる。
</pre>
<p>
コメントは、/*、で始まり、*/で終わる。この形式のコメントは、ネストできない。
</p>
<pre>
/* これはコメント*/
/*ここから
ここまでコメント*/
/* /* これはエラー。ネストしている。*/ */
</pre>
<p>
//で始まるコメントは、行末までが、コメントとなる。これは、/**/形式のコメントの中にも、書くことができる。
</p>
<pre>
// これは一行コメント。行末までがコメントとなる。
/*
// これは正しいコード。
*/
</pre>
</article>
<article>
<h1 id="lex.name"><a href="#lex.name">識別子(Identifiers)</a></h1>
<p>
識別子には、大文字小文字のアルファベット、_(アンダースコア)、数字、ユニバーサル文字名、その他の実装依存の文字が使える。大文字と小文字は区別される。
</p>
<pre>
int aaa ;
int AAA ;// aaaとは別の識別子、大文字と小文字は、区別される。
int bbb ;
int this_is_an_identifier ;
int n1234567890 ;
int \u3042 ;// ユニバーサル文字名
int 変数 ;
</pre>
<p>
ただし、識別子の先頭は、数字から始まってはならない。
</p>
<pre>
// エラー
int 0aaa ;
</pre>
<p>
また、キーワードや予約語は、識別子として使うことができない。
</p>
<pre>
// エラー、templateはキーワードである。
int template ;
// エラー、andは代替表現である。
int and ;
</pre>
<p>
以下の識別子は、特定の文法上の場所で現れた場合に、特別な意味を持つ。これは俗に、文脈依存キーワードとも呼ばれている。
</p>
<pre>
final override
</pre>
<p>
特定の文法は、識別子が現れることがない場所なので、この文脈依存キーワードは、通常通り何の問題もなく識別子として使うことができる。
</p>
<pre>
int final ; // OK
int override ; // OK
</pre>
<p>
以下のような記述も合法だ。
</p>
<pre>
// OK、クラス名finalをfinalに指定
class final final { } ;
struct base
{
virtual void override() { }
}
struct derived : base
{
// OK、virtual関数名overrideにoverrideを指定
virtual void override() override { }
} ;
</pre>
<article>
<h1 id="reserved-name"><a href="#reserved-name">予約語</a></h1>
<p>
予約語とは、C++の実装や標準ライブラリの実装のために予約されていて、使ってはならない名前のことである。ユーザーコードで予約語を使った場合、プログラムの動作は保証されない。
</p>
<p>
以下のいずれかの条件に当てはまる名前は、あらゆる利用を予約されている。
</p>
<ul>
<li>ひとつのアンダースコアに大文字から始まる名前</li>
<li>アンダースコアが二つ連続している、いわゆるダブルアンダースコアを含む名前</li>
</ul>
<p>
以下のコードは、すべて予約名を使っているので、エラーである。
</p>
<pre>
int _A ; // アンダースコアに大文字から始まる名前は、予約されている。
int __a ; // ダブルアンダースコアを含む名前は、予約されている。
int ___a ; // 三つの連続したアンダースコアも、ダブルアンダースコアを含むので、使えない。
int a__b ; // 先頭以外でも、どこかにダブルアンダースコアが含まれている場合、使えない。
int a__ ; // ダブルアンダースコアを含む
int __ ; // ダブルアンダースコアを含む
</pre>
<p>
ひとつのアンダースコアから始まる名前は、グローバル名前空間で、利用を予約されている。ただし、グローバル名前空間との名前の衝突が、時として、意外な結果をもたらすこともあるので、言語のルールの詳細を把握していない限り、利用はおすすめできない。
</p>
<pre>
// エラー、グローバル名前空間
int _a ;
// OK
namespace NS { int _a ; }
int main()
{
int _a ;// OK
}
</pre>
<p>
ひとつのアンダースコアだけの名前は、予約語ではない。
</p>
<pre>
int _ ; // OK
int __ ; // エラー、ダブルアンダースコア
</pre>
<p>
簡単にまとめると、アンダースコアから始まる名前は、使うべきではない。ダブルアンダースコアを含む名前は、あらゆる使用を禁止されている。
</p>
<p>
名前の衝突を防ぐため、しばしばC++の理解の浅い者によってアンダースコアが用いられるが、予約語と衝突した場合、コード自体の動作が保証されなくなってしまうので、名前の衝突を防ぐ目的でアンダースコアを使ってはならない。名前の衝突を防ぐためには、名前空間という言語機能がある。
</p>
</article>
</article>
<article>
<h1 id="lex.key"><a href="#lex.key">キーワード(Keywords)</a></h1>
<p>
C++では、以下のキーワードが使われている。これらのキーワードは、プログラム中で特別な意味を持つので、識別子に使うことはできない。
</p>
<pre>
alignof decltype goto reinterpret_cast try
asm default if return typedef
auto delete inline short typeid
bool do int signed typename
break double long sizeof union
case dynamic_cast mutable static unsigned
catch else namespace static_assert using
char enum new static_cast virtual
char16_t explicit noexcept struct void
char32_t export nullptr switch volatile
class extern operator template wchar_t
const false private this while
constexpr float protected thread_local
const_cast for public throw
continue friend register true
</pre>
<p>
以下は、キーワードではないが、記号と同じ意味を持つので、識別子に使うことはできない。これは、代替表現(alternative representation)と呼ばれている。
</p>
<pre>
and and_eq bitand bitor compl not
not_eq or or_eq xor xor_eq
</pre>
</article>
<article>
<h1 id="lex.literal"><a href="#lex.literal">リテラル(Literals)</a></h1>
<p>
ここでは、リテラルについて解説している。型については、<a href="#basic.types">型(Types)</a>を参照。
</p>
<article>
<h1 id="lex.icon"><a href="#lex.icon">整数リテラル(Integer literals)</a></h1>
<p>
整数リテラルには、10進数リテラル、8進数リテラル、16進数リテラルがある。C++には、2進数リテラルは存在しない。
</p>
<p>
十進数リテラルには、0123456789の文字を使うことができる。
</p>
<p>
8進数リテラルには、01234567の文字を使うことができる。プレフィクス、0から始まる整数リテラルは、8進数リテラルである。
</p>