使用类型特征时如何排列文件?

时间:2013-11-04 07:14:22

标签: c++ templates include typetraits

我第一次尝试在C ++中实现traits,但我得到多个定义符号的链接错误。

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::unordered_map相关的模板化内容来简化输出,例如std::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::的出现,使代码更具可读性。)

我如何组织我的代码文件并将其包括在内?

1 个答案:

答案 0 :(得分:1)

不要在标头中定义静态成员。您将在#include标题的每个TU中引入该定义。

一个 TU中定义它们;最简单的方法是在 .cpp 文件中。