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

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

新規登録して質問してみよう
ただいま回答率
85.47%
C++

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

Q&A

解決済

2回答

1463閲覧

自作クラスのコンストラクタにLNK2019エラーが発生する

passo_ri

総合スコア1

C++

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

0グッド

0クリップ

投稿2023/02/14 06:07

編集2023/02/14 06:18

問題

テンプレートクラスの練習をしていた際に、コンストラクタに対してLNK2019が発生してビルドが完了しない。
実は、以前にも同ファイルの関数に対して同様のエラーが発生しましたが、その時はプロトタイプ宣言を忘れていただけでした。

今回の場合は、別ファイルの為includeを忘れずに行ったのですが
別クラスの関数に対しても追加でプロトタイプ宣言は必要なのでしょうか?

TestTemplateのコンストラクタをdefault宣言するとエラーが消えたので
そもそも書き方を間違えているのでしょうか。

エラー

LNK2019 未解決の外部シンボル
"public: __cdecl TestTemplate<int>::TestTemplate<int>(int)" (??0?$TestTemplate@H@@QEAA@H@Z)
が関数 main で参照されました

補足

VisualStudio 2019
下記の3ファイルは全て同じ階層に置かれている事を確認しています。
また、ソリューションエクスプローラーにも記載済みでした。
ソースファイルを開けない旨のエラーは今のところ発生していません。

コード

main.cpp

C++

1#include "TestTemplate.h" 2 3int main(){ 4 TestTemplate<int>* intTemp = new TestTemplate<int>(1); 5 return 0; 6}

TestTemplate.h

C++

1#pragma once 2 3template<typename T> 4class TestTemplate{ 5public: 6 TestTemplate(T t); 7};

TestTemplate.cpp

C++

1#include "TestTemplate.h" 2 3template<typename T> 4TestTemplate<T>::TestTemplate(T t) {}

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

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

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

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

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

guest

回答2

0

main.cpp をコンパイルするときには TestTemplate コンストラクタの中身は不明なので TestTemplate<int> コンストラクタのコードは生成できませんし、TestTemplate.cpp をコンパイルするときには TestTemplate<int> が必要であることが不明なのでコードを生成することができません。

TestTemplate.cpp の末尾に以下のように書いて TestTemplate<int> が必要であることを明示しましょう。

cpp

1template class TestTemplate<int>;

投稿2023/02/14 06:23

int32_t

総合スコア20941

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

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

episteme

2023/02/14 06:29 編集

これも正解のひとつではあるが... 「TestTemplate<T> の T は任意の型でかまわない」ことを意図しているにもかかわらず、 この方法だと 「T は intに限る」ので、意図に反してしまうのよね。
passo_ri

2023/02/14 06:34

なるほど、理解出来ました。ありがとうございます。 ただ、型を気にせず扱える事を利点とするテンプレートでわざわざ型を宣言するのは違和感を感じますね... 私の見えないところでどのみち型が違う関数が実体化するので、宣言しなければならないのは当たり前と言えばそうなのですが...
int32_t

2023/02/14 06:39 編集

ええ、任意の型に対応したいのなら実装すべてをヘッダに書くしかないです。C++標準ライブラリのテンプレートはだいたいヘッダに実装があります。 現実的には「このプロジェクトでのみ使うテンプレート」というのもよくあるので、適用される型の種類はたいした数ではなく、この回答のような方法も珍しくありません。
passo_ri

2023/02/14 06:43

そうですね、実際に今回はある程度型が絞る事が出来るので .cppに型宣言を行うと思います。
guest

0

ベストアンサー

TestTemplate.cppの内容をTestTemplate.hに書いてください。
基本的にテンプレートの実装はヘッダに書きます。


コンパイルはファイル単位で行います。
また、テンプレートはあくまで「雛形」で、使われているテンプレート引数ごとに別物とみなします。
今回は、TestTemplate.cppにはTestTemplate<int>を使うことがわかりませんのでTestTemplate<int>は生成されません。
しかしmain.cppではTestTemplate<int>を使おうとしているのでリンクの段階でエラーになります。

ちなみにTestTemplate.cppintを使うことを宣言する。ことでも回避可能ですが、
そもそも型を特定せずに書く目的でテンプレートを使っているので、どの型で使われるかを予め宣言するのは目的に合いません。

投稿2023/02/14 06:21

編集2023/02/14 06:36
ozwk

総合スコア13528

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

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

passo_ri

2023/02/14 06:36

なるほど、ありがとうございます。 そもそもテンプレートはヘッダファイルに記載する事が基本なのですね。 となるとサイズには気を使う必要がありますね、もう少し見直してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問