スポンサーサイトCV修飾子の記述位置

Home > ----- / スポンサー広告 > This Entry 2006-02 / 実装技術 > This Entry [com : 5][Tb : 1]

--------

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

2006-02-12

一時オブジェクトの話題が続いていましたが、今回からは少し話題を変えていきたいと思います。今回は、CV修飾子の記述位置についてです。なお、「CV修飾子」というのは、const修飾子とvolatile修飾子の総称です。ちなみにC言語では、restrict修飾子もあるので、「CV修飾子」とはいわずに「型修飾子」と呼んでいます。

例えば、std::stringをconst修飾するとき、皆さんはconst std::stringと書きますか?それとも、std::string constと書きますか?C言語では、const修飾子は、よほどの事情がない限り前に付けますから、その影響で、const std::stringと書くことが多いのではないでしょうか?

では、独自の文字型として、utf8_t型というのを作ったとします。文字通り、UTF-8を扱うための型です。そして、デフォルトのchar_traitsやallocatorではなく、独自に、my_char_trais<utf8_t>クラスと、my_allocator<utf8_t>クラスを作ったとします。

この場合、utf8_t型に対応した文字列クラスは、std::basic_string<utf8_t, my_char_traits<utf8_t>, my_allocator<utf8_t> >型になります。これをconst修飾してみましょう。
const std::basic_string<utf8_t, my_char_traits<utf8_t>, my_allocator<utf8_t> >
と書くのと、
std::basic_string<utf8_t, my_char_traits<utf8_t>, my_allocator<utf8_t> > const
と書くのでは、どちらが見やすいでしょうか?

これだけだと分かりにくいかも知れませんので、utf8_t対応の文字列オブジェクトutf8_strを宣言してみましょう。
const std::basic_string<utf8_t, my_char_traits<utf8_t>, my_allocator<utf8_t> > utf8_str;
と書くのと、
std::basic_string<utf8_t, my_char_traits<utf8_t>, my_allocator<utf8_t> > const utf8_str;
と書くのでは、どちらが見やすいでしょうか?

C++では型名が非常に長くなる場合があるので、CV修飾子を後ろに書いた方が、宣言されたオブジェクトがどう修飾されているかが分かりやすくなる傾向にあります。

Comment

egtra : 2006-05-07(Sun) 16:48 URL edit
はじめまして。検索していたらたまたまここに着きました。
そもそもstd::basic_string<utf8_t, my_char_traits<utf8_t>, my_allocator<utf8_t> >という時点で見づらいです。
私なら即座にtypedefします。
typedef std::basic_string<utf8_t, my_char_traits<utf8_t>, my_allocator<utf8_t> > utf8string;
こうすればconstを前後どちらにおいても極端に見易さが変わるということは無いはずです。

ちなみに私は後ろに置いたほうが統一感があると思いつつ、慣習的に前に置いています。
たかぎ : 2006-05-08(Mon) 00:22 URL edit
egtraさん、コメントありがとうございます。

> 私なら即座にtypedefします。
ところがそうもいかないのです。
というのは、こういう長ったらしい名前をtypedefなしで使う場合というのは、大抵、テンプレート関数の引数や返却値の型なんかで、そういうときにはtypedefが使えません。

例えば、
template <class charT, class traits, class Allocator>
int func(std::basic_string<charT, traits, Allocator> const& str)
{
  ...
}
のような場合で、これだとtypedefが使えないわけです。

記事の内容が、traitsもAllocatorも特定してしまっていたので、例としてはあまりよくなかったかもしれません。
k_satoda : 2006-05-11(Thu) 01:42 URL edit
const を含む型修辞子を右に置くのは他にもメリットがあると考えていますので紹介させてもらいます。

まずは( egtra さんも挙げられていますが)宣言においての一貫性があると思います。
たとえば文字列リテラルの固定テーブルを作る場合、右に置くスタイルでは
> char const* const table[] = {...
となりますが、これを左に置くスタイルに変えるとして
> const char const* table[] = {
とはできません。以下のようにすれば正しい宣言になりますが
> const char* const table[] = {
なんだか不釣合いです。

そして、 const を左に置く人は上記の例の中の2番目の const の意味を正しく理解していない傾向があり、
> const char* table[] = {
という宣言を行いがちです。さらに、正しく理解していても忘れやすい傾向もあると感じています。
これはチープな組み込み環境では table が ROM に載るか RAM を消費するかの重大な分かれ目になります。
また、 OS から起動されるプログラムでも複数起動されたときにメモリ上のイメージを共有できるかどうかの違いになります。
たかぎ : 2006-05-11(Thu) 09:10 URL edit
k_satodaさん、コメントありがとうございます。

> そして、 const を左に置く人は上記の例の中の2番目の const の意味を正しく理解していない傾向があり、
> > const char* table[] = {
> という宣言を行いがちです。さらに、正しく理解していても忘れやすい傾向もあると感じています。
そうですね。確かに、この辺のことを十分理解できていない事例はよく見かけます。

staticなどの記憶クラス指定子は宣言全体にかかるので、
> static const char* table[] ={
だと配列が静的に確保されますが、それからの類推が働いているのかも知れません。

> さらに、正しく理解していても忘れやすい傾向もあると感じています。
忘れるというか、焦っていたり、疲れていたりすると、つまらないミスを犯すことはありますね。
: 2009-06-28(Sun) 19:19 edit
このコメントは管理人のみ閲覧できます
Post a Comment









管理者にだけ表示を許可

Trackback

http://cppemb.blog17.fc2.com/tb.php/50-457bc5c5

[プログラミング][C++]型修飾子の記述位置を変えよう

C++ (とか C) 言語の型修飾子には const,volatile (と restrict) がありまして,それぞれ意訳すると「変化しません」,「最適化しないでね」(そして「違うアドレスです」) になります.これらは型そのものとポインタ型の両方を別々に修飾できる (restrict はポインタ型だ ...

ドレッシングのような : 2006-09-17 22:35

C++と組み込み環境 | Page Top▲

New >>
固定長文字列クラス
<< old
一時オブジェクトの参照
ブログ内検索
RSSフィード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。