2013-11-04 3 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 

(나는 std::allocator, std::hash 등처럼 std::unordered_map 관련 템플릿 물건을 제거하여 출력을 단순화.)

기본적으로 특성을 사용하는 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::의 차례 나오는 제거.)

어떻게 할 내 코드 파일을 구성해야하고 작동하도록하려면 include가 필요합니까?

+1

연결 오류를 제공하십시오. – Manu343726

+0

포인터 대신 참조를 사용하십시오. – Manu343726

+0

@ Manu343726 링커 오류를 추가했습니다. 또한 예제와 관련된 std :: unordered_map 특성을 예제 소스 코드에 추가했습니다. – danijar

답변

1

머리글에 정적 멤버를 정의하지 마십시오.헤더를 갖는 각 TU에 정의를 소개합니다.

하나를 TU 대신 정의하십시오. 이 작업을 수행하는 가장 쉬운 방법은 .cpp 파일입니다.

+0

고마워, 그게 내 문제를 해결. 어쨌든, 필자의 예제에서'Fields'를 초기화하는데 어떤 다른 옵션이 있습니까? 특성 정의 머리글 어딘가에 넣고 싶습니다. – danijar

+0

C++ 11에서는 비트 주위를 뒤섞어서 인라인 이니셜 라이저를 이용할 수 있습니다. –

+0

맞습니다. VS 12가 방금 출시되었습니다. 바라기를 그들은 이것에 대한 지원을 추가했습니다. – danijar

관련 문제