c++ - 是否可以在 C++ 中将模板与其参数分开?

标签 c++ templates c++11 template-meta-programming

假设我收到一个模板的两个参数,T1 和 T2。如果我知道 T1 本身是一个模板类(例如,一个容器),而 T2 可以是任何东西,我是否可以确定 T1 的基本模板类型并使用 T2 作为其参数重新构建它?

例如,如果我收到 std::vector<int>std::string , 我想自动构建 std::vector<std::string> .但是,如果给我 std::set<bool>double , 它会产生 std::set<double> .

在这里查看 type_traits、相关博客和其他问题后,我没有看到解决此问题的通用方法。我目前认为完成此任务的唯一方法是为可以作为 T1 传入的每种类型构建模板适配器。

例如,如果我有:

template<typename T_inner, typename T_new>
std::list<T_new> AdaptTemplate(std::list<T_inner>, T_new);

template<typename T_inner, typename T_new>
std::set<T_new> AdaptTemplate(std::set<T_inner>, T_new);

template<typename T_inner, typename T_new>
std::vector<T_new> AdaptTemplate(std::vector<T_inner>, T_new);

我应该能够使用 decltype 并依靠运算符重载来解决我的问题。大致如下:

template <typename T1, typename T2>
void MyTemplatedFunction() {
  using my_type = decltype(AdaptTemplate(T1(),T2()));
}

我错过了什么吗?有更好的方法吗?

我为什么要这样做?

我正在构建一个 C++ 库,我想在其中简化用户构建模块化模板所需的操作。例如,如果用户想要构建基于代理的模拟,他们可能会配置具有生物类型、种群管理器、环境管理器和系统管理器的 World 模板。

每个管理者还需要知道有机体类型,因此声明可能类似于:

World< NeuralNetworkAgent, EAPop<NeuralNetworkAgent>,
       MazeEnvironment<NeuralNetworkAgent>,
       LineageTracker<NeuralNetworkAgent> > world;

我更希望用户不必重复 NeuralNetworkAgent每一次。如果我能够更改模板参数,则可以使用默认参数,以上可以简化为:

World< NeuralNetworkAgent, EAPop<>, MazeEnvironment<>, LineageTracker<> > world;

此外,从一种世界类型转换为另一种世界类型更容易,而无需担心类型错误。

当然,我可以使用 static_assert 处理大多数错误,只处理较长的声明,但我想知道是否有更好的解决方案。

最佳答案

这似乎以您所询问的方式工作,用 gcc 5.3.1 测试:

#include <vector>
#include <string>

template<typename T, typename ...U> class AdaptTemplateHelper;

template<template <typename...> class T, typename ...V, typename ...U>
class AdaptTemplateHelper<T<V...>, U...> {
 public:

    typedef T<U...> type;
};

template<typename T, typename ...U>
using AdaptTemplate=typename AdaptTemplateHelper<T, U...>::type;

void foo(const std::vector<std::string> &s)
{
}

int main()
{
    AdaptTemplate<std::vector<int>, std::string> bar;

    bar.push_back("AdaptTemplate");
    foo(bar);
    return 0;
}

本周最佳 C++ 问题。

关于c++ - 是否可以在 C++ 中将模板与其参数分开?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36511990/

相关文章:

c++ - 基本类型和用户定义类型的名称查找问题

栈和队列的C++默认实现

c++ - 如何在运行时将字符串转换为代码

c++ - EnumProcesses - 奇怪的行为

c++ - ID2D1Bitmap::CreateBitmap 的 srcData 是什么

c++ - 模板中的函数类型无法编译

c++ - 使用带有嵌套结构的模板化 lambda 时的类型推导 + 分析可能未使用的程序集输出

c++ - 从作为模板参数传递的 const 类型继承

c++ - 隐式与显式删除的复制构造函数

C++ 构造函数 : using this_class (gcc vs visualc)