2016-12-28 11 views
1

ビジュアルスタジオ& Solarisコンパイラでベローズコードが正常にコンパイルされています。しかしg ++(SUSE Linux)でリンクエラーが発生する4.3.4。 linuxでこのリンクエラーを修正する方法を教えてください。 注:コードをシンプルできれいにするために、私はここにプロキシコードを入力しました。 -C++ - テンプレートクラス - >静的関数 - >静的関数ポインタのリンクエラー

// ----------------

#ifndef __a1_h__ 
#define __a1_h__ 

#include <iostream> 
#include <memory> 

namespace ServiceManagement 
{ 
    template <typename T> 
    class ClassA1 
    { 
    public: 
     ClassA1() {} 

     typedef std::auto_ptr<T>(*addFunc)(int, int); 
     static void setAddFunc(addFunc f) 
     { 
      s_AddFunc = f; 
     } 

    private: 
     static addFunc s_AddFunc; 
    }; 
} 

#endif 

// ----------- a1.h -------------- b1.h -----------

#ifndef __b11_h__ 
#define __b11_h__ 

#include "a1.h" 

typedef ServiceManagement::ClassA1<int> setPosType; 

namespace ServiceManagement 
{ 
    class ClassB1 
    { 
    public: 
     ClassB1() {} 

     static void Register(); 
    private: 
     std::auto_ptr<setPosType> m_ptrMsg; 
    }; 

} 

#endif 

// ----------- ----- b1.cpp -----------

#include "b1.h" 

#include <iostream> 
using namespace std; 

//setPosType::addFunc setPosType::s_AddFunc; 
template <> setPosType::addFunc setPosType::s_AddFunc; 

namespace AA 
{ 
    namespace v2 
    { 
     std::auto_ptr<int> message2_(int a, int b) 
     { 
      int c = a + b; 

      std::auto_ptr<int> p1(new int); 
      *p1.get() = c; 

      return p1; 
     } 
    } 
} 

namespace ServiceManagement 
{ 

    void ClassB1::Register() 
    { 
     setPosType::addFunc f1 = ::AA::v2::message2_; 

     setPosType::setAddFunc(f1); 
    } 
} 

int main() 
{ 

    int i = 0; 
    cin >> i; 
    return 0; 
} 

リンクエラー: /usr/bin/C++ -pthread -g -w -W -Wall -Wno-long-long -g -ldl -lm -lnsl -m64 -o -pthread -std = gnu ++ 0x -Bdynamic

..ビルド "CMakeFiles/templateTest.dir/b1.cpp.o -o ../../../../../..//templateTest -rdynamic CMakeFiles/templateTest。 DIR/b1.cpp.o:**ServiceManagement::ClassA1<int>::setAddFunc(std::auto_ptr<int> (*)(int, int))'**: /templateTest/**a1.h:18: undefined reference toた。servicemanagement機能で:: ClassA1は:: s_AddFunc」 collect2は:ldは1つの終了ステータスを返した**

注2: すでに静的変数はb1.cppで定義されます好きな以下、 テンプレート<> setPosType :: addFunc setPosType :: s_AddFunc;初期化せずに、明らかに

template <> setPosType::addFunc setPosType::s_AddFunc = 0; 

この行は正直、私はなぜ表示されない、宣言ではなく、定義ですが、、:あなたはメンバ変数を初期化したら

+0

あなたの質問の書式はかなり混乱しています、私はエラーログの頭や尾を作ることができません。編集して、インラインコードにバッククォート( '' ')を使い、(html-escaped)出力に'

'を使用できますか? –
                        
                            
    Quentin
                                
                            
                        
                    

答えて

0

1)それは動作します。

2.)Clangは、静的メンバーを名前空間の外に定義することはC++ 11の拡張であると言います。より良い使用

namespace ServiceManagement { 
    template <> setPosType::addFunc setPosType::s_AddFunc = 0; 
} 
+0

このコードを使用しましたが、引き続き同じリンクエラーが発生しています。 – laks

+0

私は今試しました。これはメンバ変数を初期化すると動作します: 'template <> setPosType :: addFunc setPosType :: s_AddFunc = 0;'私の答えを更新します。 – JohnB