teratail header banner
teratail header banner
質問するログイン新規登録
C++

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

Q&A

4回答

1243閲覧

なぜC++ライブラリはそれが必要とするファイルをインクルードしていないのですか?

segnana

総合スコア28

C++

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

0グッド

0クリップ

投稿2022/12/26 12:16

編集2022/12/26 12:17

0

0

C++初学者です。
C++ではライブラリをインクルードする際、ライブラリが前提とするライブラリもインクルードしなければなりません。例えば以下のようなファイルa.hとb.hがあったとき、main.cppでb.hを先にインクルードした場合はエラーとなりませんが、a.hを先にインクルードするとエラーとなります。

C++

1// a.h 2void foo(){ 3 bar(); 4} 5 6// b.h 7void bar(){ 8}

a.hでb.hをインクルードするようにすれば、main.cpp内のインクルード順によらずエラーは出ません。

C++

1// a.h 2#include "b.h" 3void foo(){ 4 bar(); 5}

C++には前提となるライブラリをインクルードしていなかったり、インクルード順を間違えたりするとエラーとなるライブラリがあると思います。
なぜそれらのライブラリはそれが必要としているライブラリを自分でインクルードしていないのでしょうか?

また、このような前提ライブラリが無いことやインクルード順の間違いなどが原因のエラーに対する機械的な対処方法はありますでしょうか?

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

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

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

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

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

fana

2022/12/27 01:14

一般にそんな定義丸出しな a.h をライブラリが公開してくるとも思えないので,イマイチ伝わらない感です. もうちょっと実物を模倣したような例を出せないのでしょうか?
guest

回答4

0

例えば以下のようなファイルa.hとb.hがあったとき

inlineとしてなら別ですが、ヘッダファイル内には一般に関数の宣言だけ書いて、定義は書きません。同じ関数定義が複数あるとODR違反で正しい結果が得られません。

C++には前提となるライブラリをインクルードしていなかったり、インクルード順を間違えたりするとエラーとなるライブラリがあると思います。

そのようなライブラリは品質が悪いか、特殊な制約条件があるものだと思われます。公開されて広く使われるライブラリではあまり一般的ではありません。

投稿2022/12/26 12:28

maisumakun

総合スコア146672

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

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

0

(include の順序に依存する例にはなっていませんが)
余計な依存関係を作らないように「絶対に必要な include でないならば,include しない」という思想(?)はあるんじゃないかな,とか.

例えばこんなヘッダファイル Test.h があるとして…

C++

1//Test.h 2#pragma once 3class X; //←こういう宣言で済ませてある みたいな話かな,とか. 4const X &GetX(); 5inline int GetSomeValue(){ return 77; }

class X の定義は別のヘッダファイル X.h に書かれているとしましょう.

このヘッダ Test.h を include する側が

  • 関数 GetSomeValue() だけを使う
  • GetX() を使うけども X の定義に依存する操作は行わない

といったような場合においては,X.h を include する必要は無いわけです.
だからこそ,この Test.h 内には #include "X.h" とは書いていない,っていう.

投稿2022/12/27 01:40

fana

総合スコア12229

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

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

fana

2022/12/27 01:42

自分で書いといてアレだが,関係ない話な予感も.
fana

2022/12/27 02:19 編集

要は, "Test.h" を include した「だけ」の状態でコンパイルエラーになるようなら,それはちょっとなぁ…という感じ(Test.h 内で X.h を include しとけよ!と思う)だけど, そうではないなら,「ユーザは 本当に必要なヘッダだけを includeする」って形だから,真っ当かなぁ,みたいな. Test.h を include したら必ず X.h もくっついてきてしまい,なんとその X.h の中には大量の include が! で,それら X.h から include されているヘッダの中にもさらに include が…… みたいなの,ちょっと嫌じゃん?
guest

0

例えば以下のようなファイルa.hとb.hがあったとき、main.cppでb.hを先にインクルードした場合はエラーとなりませんが、a.hを先にインクルードするとエラーとなります。

C言語、C++言語ってのは自由な書き方のできる(ってかそこまでのチェックをしない)言語なんで、作るニンゲンの責任でどういう動作をするコードもかけます

あなたはぜひ、インクルード順が狂うとエラーになるようなコードを書かないようにしましょう

投稿2022/12/26 22:33

編集2022/12/26 22:34
y_waiwai

総合スコア88180

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

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

0

前提ライブラリが無いことやインクルード順の間違いなどが原因のエラーに対する機械的な対処方法はありますでしょうか?


的はずれな回答でしたらすみません。
何かの参考になればと思います。
#include <bits/stdc++.h>をもしご存知ないようでしたら調べてみてください。

C++を個人的な環境の学習のみで使う程度なら簡潔に書けるのでお勧めです。
但し、将来的に実務で使う予定がある場合は職場によっては使用すること自体が御法度なこともあるらしいので、
使用する場合はご自分でよく調べてから自己責任でお願いします。


参考資料
AF - 4.01.includeディレクティブ

キーポイント
#include <bits/stdc++.h>はSTL(C++の標準ライブラリ)を用いるためのもの
using namespace std;

インクルードガード
インクルードガードを行うには、ヘッダファイルの1行目に#pragma onceを書きます。

投稿2022/12/26 13:47

mjk

総合スコア303

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

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

actorbug

2022/12/26 21:34 編集

参考資料のリンク先にも書かれていますが、bits/stdc++.hは「GCC(C++コンパイラ)によって用意されているもので、他の環境(ClangやVC++など)では使えません。」 特定環境でしか使えない方法を勧めるなら、事前に質問者の環境を確認すべきだと思います。
mjk

2022/12/26 22:16

>>事前に質問者の環境を確認すべきだと思います。 的外れな回答ならすみませんと冒頭で先に断っています。 なので参考になればということとよく調べて自己責任でと但し書きしたつもりです。 ちなみにGCCでなくてもbits/stdc++.hと同等かそれに近い方法はありますし自分も以前使っていました。 実際に検索すると何件かヒットしますが質問者さんのリアクション見て追記するつもりでしたがやめておきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問