このコードでは、おかしなことになるでしょう。異なるタイプの特性を区別する必要がある場合、これは実行時ではなくコンパイル時に行う必要があります。実行している操作によっては、if
の2つのブランチのいずれかがコンパイルされないことがあります。したがって、特殊な関数に転送する方が良いでしょう。この実装手法では、使用されたブランチのみをコンパイルする必要があります(つまり正しい)。
編集:
ここではいくつかの追加情報です。この問題に対する解決策は、テンプレートのインスタンス化と関係があります。私はis_fundamental
からis_array
に切り替えて、どのように操作が失敗するかを示します。
template <class T>
void fun(T t) {
if(boost::is_array<T>::value)
{
std::cout << "true" << std::endl;
}
else
{
std::cout << "false" << std::endl;
}
}
void f(int i) {
fun(i);
}
これは、コンパイルして実行し、コンパイラは、if文の1つのブランチのみが使用され、未使用のコードとして他を削除することがわかりますでしょう:
は、最初の例から始めましょう。私は配列操作を使用する場合にはsomeithingを行います私の2番目の例では
:
template<class T>
void fun(T& t) {
if(boost::is_array<T>::value)
{
std::cout << t[0];
}
else
{
std::cout << t;
}
}
void f(int i) {
fun(i);
}
今ではコンパイルされません。理由は、テンプレート引数としてintがあるとt[0]
が形成されているためです。このランタイムステートメントを使用して、コードで必要とされるコンパイル時の型プロパティ(この例では配列を設定するプロパティとt[0]
の使用)を区別することはできません。第3の例では
我々は関数のオーバーロードを介して、コンパイル時にdisitinguishます
template<class T>
void fun_impl(boost::true_type, T& t) {
std::cout << t[0];
}
template<class T>
void fun_impl(boost::false_type, T& t) {
std::cout << t;
}
template<class T>
void fun(T& t) {
fun_impl(typename boost::is_array<T>::type(),t);
}
void f(int i) {
fun(i);
}
をここis_array<T>::type
はtrue_type
又はfalse_type
のいずれかです。この結果は、コンパイル時にfun_impl
の正しいオーバーロードを選択するためのセレクタとして使用され、選択されたオーバーロードのみがインスタンス化され、コンパイルされます。
通常、そのような技術は、タイプが特定の特性を有する場合にのみコンパイル可能な最良の実装をコモフィル時間で選択するために使用される。
第二編集:
進路変更のこの意志static if
は言語の一部である場合。
ありがとうございました。 'インクルード 'の場合+1。 – Subway