标签: template-meta-programming

您在C++中看到的最酷的元编程实例是什么?

这个问题之所以存在是因为它具有历史意义,但它不被认为是本网站的一个好的,主题上的问题,所以请不要将它作为证据,你可以在这里提出类似的问题.

更多信息:https://stackoverflow.com/faq


您在C++中看到的最酷的元编程实例是什么?
您在C++中看到的元编程有哪些实际用途?

c++ templates metaprogramming template-meta-programming

13
推荐指数
6
解决办法
8772
查看次数

从迭代器获取const_iterator

可能重复:
从迭代器获取const_iterator

我想写一元函数返回相应的const_iteratoriterator

template <class Iterator>
struct get_const_iterator
{
    typedef ??? type;
};
Run Code Online (Sandbox Code Playgroud)
  • get_const_iterator<int*>::type 一定是 const int*
  • get_const_iterator<const int*>::type 一定是 const int*
  • get_const_iterator<int* const>::type必须是const int*const int* const,我不在乎
  • get_const_iterator<std::list<char>::iterator>::type 一定是 std::list<char>::const_iterator

等等

可以使用iterator_traits或不使用它们吗?

编辑:我们假设如果2个容器具有相同的iterator类型,那么它们也具有相同的const_iterator类型.我认为这是一个合理的假设,虽然理论上并不完全正确.

c++ templates iterator stl template-meta-programming

13
推荐指数
1
解决办法
1713
查看次数

如何检查类型是否是给定类模板的实例化?

是否可以检查类型是否是特定模板的实例化?

我有一个类模板,其中一个模板参数必须是特定模板的实例化,或其他类型.例如,考虑一个类型列表的简单定义:

struct null_type;

template <typename Head, typename Tail>
struct typelist
{
    // Tail must be a typelist or null_type

    typedef Head head;
    typedef Tail tail;
};
Run Code Online (Sandbox Code Playgroud)

现在,我想,以确保规定的类型Tail模板参数始终为的一个实例typelistnull_type.我可以使用部分特化来仅为这些情况定义模板,如下所示:

template <typename Head, typename Tail>
struct typelist; // default, not defined

template <typename Head, typename H, typename T>
struct typelist< Head, typelist<H,T> > // Tail = typelist, ok
{
    typedef Head head;
    typedef typelist<H,T> tail;
};

template <typename Head>
struct typelist< Head, null_type > // Tail …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-meta-programming

13
推荐指数
1
解决办法
3219
查看次数

Scala宏,它们在哪里使用?

我只是注意到Scala有宏,但我从未见过任何使用它们的代码.它们似乎与C预处理器宏等完全不同.通过阅读宏的概述,看起来它们看起来不像以前在Scala中提供的任何东西.在动机标题下,有一个宏启用的事项列表:

  • 语言虚拟化(原始编程语言的重载/覆盖语义,以实现DSL的深度嵌入),
  • 程序具体化(为程序提供检查自己代码的方法),
  • 自我优化(基于程序实现的特定于域的优化的自我应用),
  • 算法程序构造(使用编程语言支持的抽象编写繁琐的代码).

稍后在菜单中,有实验宏功能,例如类型宏,quasiquotes,无类型宏等等.显然需要这个!

对于那些构建非常复杂的库并且对Scala有深刻理解的人来说,所有这些看起来都很不错.但是宏也为普通的Scala开发人员提供了一些东西吗?使用宏会使我的Scala代码变得更好吗?

macros scala metaprogramming template-meta-programming

13
推荐指数
1
解决办法
4891
查看次数

变量模板别名作为模板参数(第2部分)

这是另一个问题的后续行动.它指的是同样的问题(我希望),但使用一个完全不同的例子来说明它.原因是在前面的示例中,只有实验性GCC 4.9因编译器错误而失败.在此示例中,Clang和GCC 4.8.1也以不同方式失败:Clang产生意外结果,GCC 4.8.1报告不同的错误消息.

上一个问题的答案或多或少地说代码是有效的,问题在于GCC的实验版本.但这个结果让我更加怀疑.几个月来我一直困扰着我怀疑有相关(或相同)的问题,这是我第一次有一个小的具体例子来说明.

所以,这里有一些代码.首先,一些通用代码将SFINAE应用于由可变参数模板别名元函数指定的任意测试F:

#include <iostream>
using namespace std;

using _true  = integral_constant <bool, true>;
using _false = integral_constant <bool, false>;

template <typename T> using pass = _true;

template <template <typename...> class F>
struct test
{
    template <typename... A> static _false           _(...);
    template <typename... A> static pass <F <A...> > _(int);
};

template <template <typename...> class F, typename... A>
using sfinae = decltype(test <F>::template _<A...>(0));
Run Code Online (Sandbox Code Playgroud)

第二,一个特定的测试,检查给定的类是否定义了一个名为的类型type:

template <typename T> using type_of  = …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-meta-programming variadic-templates template-aliases

13
推荐指数
1
解决办法
859
查看次数

Constexpr如果替代

我想constexpr if在编译时使用分支,但最新的MSVC编译器似乎不支持它.有以下替代方案吗?:

template<typename T>
void MyFunc()
{
    if constexpr(MeetsConditions<T>::value)
    {
        FunctionA<T>();
    }
    else
    {
        FunctionB<T>();
    }
}
Run Code Online (Sandbox Code Playgroud)

简而言之:我可以模拟constexpr if编译器不支持的时间吗?

c++ template-meta-programming c++17

13
推荐指数
5
解决办法
3975
查看次数

如何在c ++中使用typedef作为泛型类

我正在尝试使用unordered_map.但在某些服务器中我们没有tr1库.在那些情况下,我想使用地图.所以,我想写一个头文件,我将使用以下行之一.

typedef tr1::unordered_map hashmap;
typedef map hashmap;
Run Code Online (Sandbox Code Playgroud)

我的问题是我在这里使用不同类型的地图.

map<string, string>
map<string, int>
map <string, map<string,int>> ..etc
Run Code Online (Sandbox Code Playgroud)

如果我可以使用的typedef别名地图或unordered_map为HashMap,那么我可以使用地图的hashmap<string, string>,hashmap<int, int>在代码中.

有没有办法做到这一点或如果有更好的方法请建议我.

谢谢Vinod

c++ typedef template-meta-programming

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

通过索引在运行时访问std :: tuple元素的最佳方法

我有一个函数at旨在通过运行时指定的索引访问std :: tuple元素

template<std::size_t _Index = 0, typename _Tuple, typename _Function>
inline typename std::enable_if<_Index == std::tuple_size<_Tuple>::value, void>::type
for_each(_Tuple &, _Function)
{}

template<std::size_t _Index = 0, typename _Tuple, typename _Function>
inline typename std::enable_if < _Index < std::tuple_size<_Tuple>::value, void>::type
    for_each(_Tuple &t, _Function f)
{
    f(std::get<_Index>(t));
    for_each<_Index + 1, _Tuple, _Function>(t, f);
}

namespace detail { namespace at {

template < typename _Function >
struct helper
{
    inline helper(size_t index_, _Function f_) : index(index_), f(f_), count(0) {}

    template < typename _Arg …
Run Code Online (Sandbox Code Playgroud)

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

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

优化交换机的模板替换

我的一个项目中有很多自定义数据类型,它们共享一个公共基类.

我的数据(来自数据库)有一个数据类型,它由基类的枚举区分.我的体系结构允许特定的数据类型专门用于派生类,或者它可以由基类处理.

当我构造一个我特定的数据类型时,我通常直接调用构造函数:

Special_Type_X a = Special_Type_X("34.34:fdfh-78");
a.getFoo();
Run Code Online (Sandbox Code Playgroud)

有一些模板魔术也可以像这样构建它:

Type_Helper<Base_Type::special_type_x>::Type a =  Base_Type::construct<Base_Type::special_type_x>("34.34:fdfh-78");
a.getFoo();
Run Code Online (Sandbox Code Playgroud)

对于枚举类型的某些值,可能没有专门化

Type_Helper<Base_Type::non_specialized_type_1>::Type == Base_Type
Run Code Online (Sandbox Code Playgroud)

当我从数据库中获取数据时,在编译时不知道数据类型,因此有第三种方法来构造数据类型(来自QVariant):

Base_Type a = Base_Type::construct(Base_type::whatever,"12.23@34io{3,3}");
Run Code Online (Sandbox Code Playgroud)

但是我当然希望调用正确的构造函数,所以该方法的实现过去看起来像:

switch(t) {
     case Base_Type::special_type_x:  
        return Base_Type::construct<Base_Type::special_type_x>(var);

     case Base_Type::non_specialized_type_1:  
        return Base_Type::construct<Base_Type::non_specialized_type_1>(var);              

     case Base_Type::whatever:  
        return Base_Type::construct<Base_Type::whatever>(var);     

     //.....
}
Run Code Online (Sandbox Code Playgroud)

这段代码是重复的,因为基类也可以处理新类型(添加到枚举),我提出了以下解决方案:

// Helper Template Method
template <Base_Type::type_enum bt_itr>
Base_Type construct_switch(const Base_Type::type_enum& bt, const QVariant& v)
{
  if(bt_itr==bt)
    return Base_Type::construct<bt_itr>(v);
  return construct_switch<(Base_Type::type_enum)(bt_itr+1)>(bt,v);
}

// Specialization for the last available (dummy type): num_types
template <>
Base_Type construct_switch<Base_Type::num_types>(const Base_Type::type_enum& bt, const QVariant&)
{ …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-meta-programming

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

是否有可能将模板与其在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
查看次数