質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.54%
型推論

型推論とは、コンパイラが型を自動で判断する機能を指します。メソッド内のローカル変数の宣言時に型宣言の代わりに指定することで、コードの記述量を減らすことが可能。変数や関数シグネチャに型を宣言せずとも、早期にエラーをチェックできるというメリットもあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

LLVM

LLVM とは、コンパイル時や実行時に様々な最適化をするコンパイラ基盤です。 任意のプログラミング言語に対応可能で、LLVM自体はC++で実装されています。

Q&A

解決済

2回答

984閲覧

C++ テンプレートクラスを宣言した後に行うconstの宣言について llvmのソースコードリーティング

Kchan_01

総合スコア110

型推論

型推論とは、コンパイラが型を自動で判断する機能を指します。メソッド内のローカル変数の宣言時に型宣言の代わりに指定することで、コードの記述量を減らすことが可能。変数や関数シグネチャに型を宣言せずとも、早期にエラーをチェックできるというメリットもあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

LLVM

LLVM とは、コンパイル時や実行時に様々な最適化をするコンパイラ基盤です。 任意のプログラミング言語に対応可能で、LLVM自体はC++で実装されています。

0グッド

0クリップ

投稿2022/01/07 07:46

編集2022/01/07 07:48

C言語を学んでから、C++を学んでいるものです。

C++のvectorの再実装をするためにllvmのソースコードリーティングをしています。そこで理解できないコードがあったので質問します。

c++

1template <class _Tp, _Tp __v> 2struct integral_constant { 3 static const _Tp value = __v; 4 typedef _Tp value_type; 5 typedef integral_constant type; 6 operator value_type() const _NOEXCEPT { return value; } 7}; 8 9template <class _Tp, _Tp __v> // <= ここがわかりません 10const _Tp integral_constant<_Tp, __v>::value; // <= ここがわかりません

libcxx/type_traits at master · llvm-mirror/libcxx

テンプレートクラスを宣言した後にconstで変数の宣言をしているようです。これはグローバル変数を宣言しているのでしょうか。これにはどういった意味があるのでしょうか。

c++

1template <class _Tp, _Tp __v> 2const _Tp integral_constant<_Tp, __v>::value;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

私はC++規格に対して正確な理解をしてないので、以下は雰囲気で書いてますが、ものすごく間違えていることはないはず...。

このコードは、まずtemplateを無視してクラスのstaticメンバ変数の実装として見てください。そうすると理解が早いです。

C++

1class Hoge 2{ 3 // Hogeのstaticメンバ変数としてint型のvalueがあるよ、という宣言。 4 static int value; 5}; 6 7// Hogeクラスのvalueメンバ変数の実体を定義。初期値は100。 8int Hoge::value = 100;

後者の「int Hoge::value = 100;」を削ってビルドすると、「Hoge::valueの実体がどこにも無いよ」というリンクエラーが発生すると思います。つまり、前者のクラス内の宣言だけでは、変数の実体が存在しないのです。なので後者が合わせて必要になります。

このvalueについて、const修飾して定数化したものが以下のコードになります。

C++

1class Hoge 2{ 3 static const int value; 4}; 5const int Hoge::value = 100;

クラステンプレートのstaticメンバ変数の実体を定義する場合、(C++には部分特殊化などもありますので)どんなテンプレートに対する実体定義なのかを明示する必要があります。以下をコンパイルして実行したら、理解が早いのではないでしょうか。

C++

1#include <iostream> 2 3template <typename T, T i> 4struct Hoge 5{ 6 static const T value; 7}; 8template <typename T, T i> 9const T Hoge<T, i>::value = i; 10 11template <> 12const int Hoge<int, 100>::value = 200; 13 14int main() 15{ 16 std::cout << Hoge<long, 123>::value << std::endl; 17 std::cout << Hoge<int, 100>::value << std::endl; 18}

投稿2022/01/07 08:34

ttact

総合スコア166

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttact

2022/01/07 08:38

SaitoAtsushiさんのコメントにありますが、const修飾(あるいはconstexpr修飾)されたstaticメンバ変数は、クラス外での定義は不要だったりします。
guest

0

static 修飾されているので、クラス変数の定義です(フツーのインスタンス変数ではなく)
※ クラス変数は クラスごとに唯一ひとつ定義せにゃならんので

投稿2022/01/07 08:04

編集2022/01/07 08:06
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kchan_01

2022/01/07 08:18

クラスの中で`static const _Tp value = __v;`と定義されているので、クラスの外で定義を書いている理由が理解できないです。 `const _Tp integral_constant<_Tp, __v>::value;`は代入されていないので、定義ではなく、宣言に見えるのですが、どういった記法なのでしょうか。
fana

2022/01/07 08:19

> static const _Tp value = __v; として初期値が宣言側に書かれているのは何故なのだろう? 定義の側に書くのだと思ってたけど,それだとまずいのだろうか?(あるいはどっちでもいい?)
SaitoAtsushi

2022/01/07 08:31 編集

static const の場合はクラスの外で改めて定義する必要はないです。 単に二度宣言した扱いで許容されるだけで、無ければなくても問題ないはずです。 ただ、コンパイラのバグとかなんやかやでなければ動作しないケースとかが過去にあったとかかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.54%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

同じタグがついた質問を見る

型推論

型推論とは、コンパイラが型を自動で判断する機能を指します。メソッド内のローカル変数の宣言時に型宣言の代わりに指定することで、コードの記述量を減らすことが可能。変数や関数シグネチャに型を宣言せずとも、早期にエラーをチェックできるというメリットもあります。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

LLVM

LLVM とは、コンパイル時や実行時に様々な最適化をするコンパイラ基盤です。 任意のプログラミング言語に対応可能で、LLVM自体はC++で実装されています。