用于逻辑拆分的非类型模板

时间:2015-06-05 13:34:03

标签: c++ templates design-patterns

我有以下情况,我不知道我的方法是否正确。我正在开发一个具有以下结构的项目:

{
    "options": 
    [
        [
        "category 1",
        "category 1",
            [
                [
                "subcategory 1",
                "subcategory 1",
                    [
                        [
                        "item 1",
                        "item 1"
                        ],
                        [
                        "item 2",
                        "item 2"
                        ]
                    ]
                ],
                [
                "subcategory 2",
                "subcategory 2",
                    [
                        [
                        "item 1",
                        "item 1"
                        ],
                        [
                        "item 2",
                        "item 2"
                        ]
                    ]
                ]
            ]
        ]
    ]
}

该类使用Operation抽象来运行OpenFile操作,ReadFile操作等。操作被发送到负责相关文件系统类型的路由器。

class Filesystem {
public:
      Filesystem(Profile* profile);
      OpenFile(const std::string& file,OpenFileCallback);
      ReadFile(int file_handle,Buffer* buffer,ulong offset,ulong length);
protected:
    DiskRouter* disk_router_;
...
}

// --- implementation ---
Filesystem::Filesystem(Profile* profile) 
    :disk_router_(Disk_Router::Get(profile)){
}

我想使用选择目标路由器的非类型参数和目标策略来在路由器之间进行选择。基本上代码是可重用的,我不想改变一个好的实现,如果有什么变化可用于所有逻辑。 类似的东西:

class Operation {
public:
    Operation(Disk_Router* router) {
    }
}

该行动将成为:

template <int DESTINATION>
class Filesystem{
 ...
protected:
  Destination_Policy<DESTINATION>::DestinationType router_type;
}
// ----- implementation
template <int DESTINATION>
Filesystem<DESTINATION>::Filesystem(Profile* profile)
      :disk_router_(Destination_Policy<DESTINATION>::Get(profile)) {
}

我想要实现的目标:

  • 我不需要描述路由器的通用接口。它们可以独立变化

  • 如果需要,我可以根据非类型

  • 专门化某些方法

这个逻辑是否正确? 谢谢!

1 个答案:

答案 0 :(得分:0)

我想到了两件事,但由于您的问题仅显示了代码的一小部分,因此只有您可以判断它们是否适用:

首先,int没有任何实际意义。我假设可能值的数量及其含义应该限制在特定的集合中,因此使用enum(如果C ++ 11可用,则更好的enum class)似乎更合适。您仍然可以像int一样专注,只需要您的代码更易读,更不容易出错。

但第二件事和IMHO真正的问题是,为什么你需要非类型参数呢?您似乎可以直接传递策略类型:

template <typename DestinationPolicy>
class Filesystem{
 ...
protected:
  typename DestinationPolicy::DestinationType disk_router_;
}
// ----- implementation
template <typename DestinationPolicy>
Filesystem<DestinationPolicy>::Filesystem(Profile* profile)
      :disk_router_(DestinationPolicy::Get(profile)) {
}

如果您的大多数策略最终看起来几乎相同,请为它们创建基类,并仅覆盖实际策略所需的内容。与基于enum的解决方案相比,它还可以使您更加灵活,因为您可以在以后添加任意数量的策略,并为每个策略指定一个描述性名称。