2012-03-23 13 views
1

ローカル関数をシミュレートする方法としてローカルクラスを使用しようとしていました。ローカルクラスは、いくつかの静的ヘルパー関数を定義しています。各静的関数は、関数スコープで定義された静的配列にアクセスする必要があります。事は正常な機能のために働いていますが、私はテンプレート関数を使用するときにリンクエラーがあります。コードは次のとおりです。ローカルクラスと関数テンプレート

#include <iostream> 

double test_local (double x) 
{ 
    static const double coeff[3]={ 0, 1, 2 }; 

    struct local_functions 
    { 
     static double f0 (double x) 
     { 
      static const double c0=coeff[0]+coeff[1]; 
      return c0+x; 
     } 

     static double f1 (double x) 
     { 
      static const double c1=coeff[1]+coeff[2]; 
      return c1+x; 
     } 

     static double f2 (double x) 
     { 
      static const double c2=coeff[2]+coeff[0]; 
      return c2+x; 
     }  
    }; 

    return local_functions::f0(x)+local_functions::f1(x)+local_functions::f2(x); 
} 

template<class t> 
t test_local_tmpl (t x) 
{ 
    static const t coeff[3]={ 0, 1, 2 }; 

    struct local_functions 
    { 
     static t f0 (double x) 
     { 
      static const t c0=coeff[0]+coeff[1]; 
      return c0+x; 
     } 

     static t f1 (t x) 
     { 
      static const t c1=coeff[1]+coeff[2]; 
      return c1+x; 
     } 

     static t f2 (t x) 
     { 
      static const t c2=coeff[2]+coeff[0]; 
      return c2+x; 
     } 
    }; 

    return local_functions::f0(x)+local_functions::f1(x)+local_functions::f2(x); 
} 

int main (int argc, char** argv) 
{ 
    double result=test_local (1e0); 

    // uncommenting next line generates a linking error 
    // double result_tmpl=test_local_tmpl (1e0); 

    std::cout << result << std::endl; 
    return 0; 
} 

非テンプレート関数が正常に動作します(それは9を印刷します)、私はテンプレートのバージョンを起動しようとすると、それは罰金コンパイルするが、G ++の下にリンクしませんが - 4.6:

g++ -c -g local_class.cpp && g++ local_class.o -o local_class 
Undefined symbols: 
    "coeff", referenced from: 
     double test_local_tmpl<double>(double)::local_functions::f2(double) in local_class.o 
     double test_local_tmpl<double>(double)::local_functions::f2(double) in local_class.o 
     double test_local_tmpl<double>(double)::local_functions::f1(double) in local_class.o 
     double test_local_tmpl<double>(double)::local_functions::f1(double) in local_class.o 
     double test_local_tmpl<double>(double)::local_functions::f0(double) in local_class.o 
     double test_local_tmpl<double>(double)::local_functions::f0(double) in local_class.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

これは予想されるbeahaviourですか、私は何か、または何が欠けているのですか?

+0

[STLアルゴリズムでのローカルクラスの使用](http://stackoverflow.com/questions/742607/using-local-classes-with-stl-algorithms)の可能な複製。テンプレート内のローカルクラスを使用しないという制限はC++ 11から削除されましたが、gcc4.6がそれを実装しているかどうかわかりません - もう一度考えれば、重複しているとは確信していません。そのように配置されたコードで質問を処理します。 –

+4

ひどい書式設定です。 – Nawaz

+0

@DavidRodríguez-dribeas:リンク時に問題があります。**コードはうまくコンパイルされます**。いずれにしても、-std = C++ 0xフラグを追加すると同じ問題が発生します。 – Giuliano

答えて

1

これはGCCのバグです。コードにエラーはありません。バグレポートを提出してください。

+0

私は..... – Nawaz

+0

ところで、それはGCC-4.5.1で修正されていると思い – Nawaz

+0

良い@Nawaz、私は私の答えにそれを追加します –

0

回避策 gcc開発者から純粋なソリューションを待っている間に問題を回避するために、この問題を回避してください。最終的な決定は、ヘルパー機能を持たない従来の実装に切り替えることでした。はるかにエレガントではありませんが(もちろん)、それは重要です。

私は他のコンテキスト(多分)で役に立つかもしれないので、とにかく私はここで "解決策"を提示します。コードの書式設定があなたの目を傷つけることはないと思っています:)今回は。

#include <iostream> 
#include <complex> 

template<class t> 
t test_local_tmpl (t x) 
{ 
    struct local_functions 
    { 
    static const t* coeff() 
    { 
     static const t c[]={0,1,2}; 
     return c; 
    } 

    static t f0 (t x) 
    { 
     static const t c0=coeff()[0]+coeff()[1]; 
     return c0+x; 
    } 

    static t f1 (t x) 
    { 
     static const t c1=coeff()[1]+coeff()[2]; 
     return c1+x; 
    } 

    static t f2 (t x) 
    { 
     static const t c2=coeff()[2]+coeff()[0]; 
     return c2+x; 
    } 
    }; 

    return local_functions::f0(x)+local_functions::f1(x)+local_functions::f2(x); 
} 

int main (int argc, char** argv) 
{ 
    std::cout << test_local_tmpl (1e0) << std::endl; 
    std::cout << test_local_tmpl (std::complex<double>(1e0)) << std::endl; 
    return 0; 
} 

、出力が

$ g++-mp-4.6 -c -g local_class.cpp && g++-mp-4.6 local_class.o -o local_class 
$ ./local_class 
9 
(9,0) 

です。とにかくローカルクラスは、おそらく彼らはC++の設計上のアレキの本から出て旅をしたことがない言語では、このようなコーナー機能していることと思われます。このIMHOを確認する前にバグが発見されなかったという事実。

関連する問題