小编Cha*_*ria的帖子

是否有可能将模板与其在C++中的参数区分开来?

假设我收到一个模板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);
Run Code Online (Sandbox Code Playgroud)

我应该能够使用decltype并依赖运算符重载来解决我的问题.有点像:

template <typename T1, typename T2>
void MyTemplatedFunction() {
  using my_type = decltype(AdaptTemplate(T1(),T2()));
}
Run Code Online (Sandbox Code Playgroud)

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

我为什么要这样做?

我正在构建一个C++库,我希望简化用户构建模块化模板所需的操作.例如,如果用户想要构建基于代理的模拟,他们可能会配置具有生物类型的世界模板,人口管理器,环境管理器和系统管理器.

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

World< NeuralNetworkAgent, EAPop<NeuralNetworkAgent>,
       MazeEnvironment<NeuralNetworkAgent>,
       LineageTracker<NeuralNetworkAgent> > world;
Run Code Online (Sandbox Code Playgroud)

我宁愿用户不必NeuralNetworkAgent每次都重复.如果我能够更改模板参数,则可以使用默认参数,并且可以将上述内容简化为:

World< NeuralNetworkAgent, EAPop<>, MazeEnvironment<>, LineageTracker<> > world;
Run Code Online (Sandbox Code Playgroud)

此外,从一种世界类型转换为另一种世界类型更容易,而不必担心类型错误.

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

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

12
推荐指数
1
解决办法
267
查看次数

如果没有 if-constexpr 成功,触发编译时错误的最佳方法是什么?

我有一系列很长的if constexpr语句,如果没有一个成功,我想触发编译时错误。

具体来说,我有一个抽象语法树,我想将其结果转换为我可能需要的一组特定类型。我有 AsInt()、AsDouble() 等正在工作,但我需要能够根据提供的类型更动态地执行此操作。

就目前情况而言,我已经编写了一个模板化的 As() 成员函数,但它的错误检查很笨拙。具体来说,使用静态断言需要一个笨拙的测试条件。这是一个简化版本:

template <typename T>
T As() {
  if constexpr (std::is_same_v<T,int>) return AsInt();
  if constexpr (std::is_same_v<T,double>) return AsDouble();
  ...
  if constexpr (std::is_same_v<T,std::string>) return AsString();

  static_assert( std::is_same_v<T,int>
                 || std::is_same_v<T,double>
                 || ...
                 || std::is_same_v<T,std::string>,
                 "Invalid template type for As()" );
}
Run Code Online (Sandbox Code Playgroud)

如果所有条件都失败,是否有更简单的方法来触发静态断言(或等效方法)?

c++ static-assert type-traits if-constexpr

4
推荐指数
1
解决办法
884
查看次数