はじめに
TwitterでWandboxのコードを呟いてたら、親切なお方が「分離コンパイルできますよ?」と教えてくれたので早速やってみた。
ついでに、テンプレートの明示的インスタンス化もやってみたかったので書いてみた(というより、テンプレートクラスで分離コンパイルやろうとしていたので、結果的に明示的インスタンス化せざるを得なかった……)
実際のコード
実際に書いたコードはこちら
https://wandbox.org/permlink/JzhacAWqke6pZtEe
ザクっとコードの解説ー
まず、TemplateContainer.hpp
からー
#ifndef TEMPLATE_CONTAINER_HPP_
#define TEMPLATE_CONTAINER_HPP_
#include <vector>
template <typename T>
class Container{
private:
std::vector<T> container;
public:
void set(T var);
void show();
};
template class Container<int>;
#endif
#ifndef
と #endif
はインクルードガードだねー。
で、std::vector<T> container
というメンバ変数と、set(T var)
show()
というメンバ関数を持つContainerクラスを定義している。
で、ヘッダの最後に template class Container<int>
と記述することが今回のミソの一つ。
これがないと分離コンパイルの時にエラーが発生する。
詳しい解説はこちらが参考になるので参照されたし
テンプレート関数の宣言と実装を分離する方法
テンプレート関数の宣言と実装を分離する方法 ( 補足 )
次に、TemplateContainer.cpp の実装部分。
#include <iostream>
#include "TemplateContainer.hpp"
template <typename T>
void Container<T>::set(T var){
container.emplace_back(std::move(var));
}
template <typename T>
void Container<T>::show(){
for(auto&& c : container)
std::cout << c << std::endl;
}
set(T var) は入力されたデータを動的配列 container に格納してる。
show() は 範囲for文(The range-based for statement)使って入力されたデータを一つづつ出力している。
で、最後にmain() のソース
#include <iostream>
#include <vector>
#include "TemplateContainer.hpp"
int main(){
Container<int> cont;
for(int i = 0; i < 1000; i++)
cont.set(i);
cont.show();
return 0;
}
for文
で 0 ~ 999 までの数字を動的配列に入力してる(999までにしたのは銀河鉄道999が好きだから)。
その後、set()
で出力させてる。
そいで、ここが一番のキモだけど Wandbox の画面左端にある「Compiler options」に 実装が書いてある TemplateContainer.cpp
を入力。
これで Wandbox で分離コンパイルができる。
どうも分離コンパイルする際には、実装部分のソースを「Compiler options」に渡してやればいい模様。
より詳しい解説は下記の記事に書かれているので参考にされたし
君はまだWandboxの真の実力を知らない~C++er目線で~
おわりに
基本的には、「Compiler options」に実装部分のソースを渡してやればコンパイルできる。
ただ、僕の場合は変にテンプレートクラスを実装と定義に分けてコンパイルしようとしたので変に詰まっちゃったんだけどね……
まあ、普通に実装と定義を分けて書く分には問題ないと思う。