2013-11-04 28 views
4

我第一次嘗試在C++中實現特徵,但是我得到了多個定義符號的鏈接錯誤。如何在使用類型特徵時安排文件?

error LNK2005: "public: static class std::unordered_map<std::string, std::string> const ManagerTrait<struct Specialized>::Fields" 
error LNK2005: "public: static class std::unordered_map<std::string, std::string> const ManagerTrait<struct Specialized>::Fields" 
error LNK2005: "public: static class std::unordered_map<std::string, std::string> const ManagerTrait<struct Specialized>::Fields" 
error LNK2005: "public: static class std::unordered_map<std::string, std::string> const ManagerTrait<struct Specialized>::Fields" 
error LNK2005: "public: static class std::unordered_map<std::string, std::string> const ManagerTrait<struct Specialized>::Fields" 
error LNK2005: "public: static class std::unordered_map<std::string, std::string> const ManagerTrait<struct Specialized>::Fields" 
error LNK1169: one or more multiply defined symbols found 

(I通過去除有關std::unordered_mapstd::allocatorstd::hash,等等模板東西簡化了輸出。)

基本上,有一個Manager類,它使用的性狀,一個默認的性狀班級和一些專業特點。但是所有特殊性狀都需要訪問Manager類的嵌套類型。

manager.h

#pragma once 

class Manager 
{ 
    class Parameter 
    { 
     // ... 
    }; 

    template <typename T> 
    void Usage(T* Instance) 
    { 
     typedef ManagerTrait<T> Trait; 

     // access unordered map 
     for(auto i : Trait::Fields) { /* ... */ } 

     // access function 
     Parameter parameter; 
     Trait::Function(Instance, &parameter); 
    } 
} 

// would like to move that in dedicated manager/trait.h 
template <typename T> 
struct ManagerTrait; 

specialized.h

#pragma once 
#include "manager.h" 

class Specialized 
{ 
    // ... 
}; 

// would like to move in a dedicated specialized/trait.h 
template <> 
struct ManagerTrait<Specialized> 
{ 
    // define unordered map 
    static const unordered_map<string, string> Fields; 

    // define function 
    static void Function(Specialized *Instance, Manager::Parameter *Parameter) 
    { 
     // ... 
    } 
}; 

// populate unordered map 
const unordered_map<string, string> ManagerTrait<Specialized>::Fields = []{ 
    unordered_map<string, string> fields; 
    // insert some elements 
    // ... 
    return fields; 
}(); 

(我刪除了命名空間std::的occurances使代碼更易讀。)

我如何需要組織我的代碼文件幷包含它以使其工作?

+1

提供鏈接錯誤,請 – Manu343726

+0

考慮使用引用而不是指針 – Manu343726

+0

@ Manu343726我添加了鏈接錯誤。而且,我在示例源代碼中添加了trad的std :: unordered_map成員,因爲它可能與問題有關。 – danijar

回答

1

不要在標頭中定義靜態成員。您將在每個TU中引入定義,即頭部。

定義它們在之一 TU代替;最簡單的方法是在.cpp文件中。

+0

謝謝,這解決了我的問題。無論如何,我有什麼其他選項來初始化我的示例中的'Fields'?我想把它放在特徵定義頭部的某個地方。 – danijar

+0

在C++ 11中,如果你隨機播放一些內容,你可能會利用內聯初始化器。 –

+0

你是對的,VS 12剛剛發佈。希望他們增加了對此的支持。 – danijar

相關問題