标签: template-meta-programming

模板元编程递归上限?

我正在编写一个非常简单的模板类,使用元编程在编译时计算总和,如下所示:

#include <iostream>

using namespace std;

template<int N>
class Sum
{
    public:
        enum {value = N + Sum<N-1>::value };
};

template<>
class Sum<0>
{
    public:
        enum {value = 0};
};


int main()
{
    cout << Sum<501>::value << endl;
}
Run Code Online (Sandbox Code Playgroud)

有趣的是:

  • 当我打印Sum <500>及以下时,它工作正常
  • 当谈到Sum <501>时,编译失败了:

    sum.cpp:9:从Sum<500>' sum.cpp:9: instantiated fromSum <501>'sum.cpp:22实例化:从这里实例化

    sum.cpp:9:错误:不完整的类型Sum<1>' used in nested name specifier sum.cpp:9: error: enumerator value for值'不是整数常量

  • Sum <501>将报告Sum <1>的错误,Sum <502>将报告Sum <2>的错误,差值始终为2,在我看来编译器的限制资源为500.

对此有何想法?他们是打破这种限制的一种方式吗?

谢谢.

编辑:
谢谢大家,重点不是关于算法,而是编译器的限制 - 我知道有一个简单的方法来获得总和:)

EDIT2:

  • 使用gcc 4.6 +,错误信息更有帮助

    sum.cpp:9:14:错误:模板实例化深度超过1024的最大值(使用-ftemplate-depth …

c++ templates template-meta-programming

14
推荐指数
2
解决办法
7223
查看次数

如何在编译时订购类型?

考虑以下程序:

#include <tuple>
#include <vector>
#include <iostream>
#include <type_traits>

template <class T>
struct ordered {};

template <class... T>
struct ordered<std::tuple<T...>>
{
    using type = /* a reordered tuple */;
};

template <class T>
using ordered_t = typename ordered<T>::type;

int main(int argc, char* argv[])
{
    using type1 = std::tuple<char, std::vector<int>, double>;
    using type2 = std::tuple<std::vector<int>, double, char>;
    std::cout << std::is_same_v<type1, type2> << "\n"; // 0
    std::cout << std::is_same_v<ordered_t<type1>, ordered_t<type2>> << "\n"; // 1
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

ordered助手有重新排序的元组类型,使得两个元与萨姆斯的类型,但有序的不同导致相同的元组类型:它可以是第一个,第二个,甚至是另一个问题:它只是有相同的大小,相同的元素,但以一个独特的顺序(无论这个顺序如何).

是否可以使用模板元编程技术在编译时执行此操作?

c++ types tuples template-meta-programming c++17

14
推荐指数
1
解决办法
519
查看次数

计算lambda中的参数数量

我需要知道lambda具有的确切参数数量.我不关心他们的类型,我只需要一个计数.

auto lambda0 = [&]() { ... };
auto lambda1 = [&](int32_t a) { ... };
auto lambda2 = [&](int32_t a, auto b) { ... };

lambda_details<decltype(lambda0)>::argument_count; // Equals 0
lambda_details<decltype(lambda1)>::argument_count; // Equals 1
lambda_details<decltype(lambda2)>::argument_count; // Equals 2
Run Code Online (Sandbox Code Playgroud)

检测变量lambda也很好,所以我也可以处理那个边缘情况.

auto lambda_variadic = [&](auto... args){ ... };

lambda_details<decltype(lambda_variadic)>::is_variadic; // Equals true
Run Code Online (Sandbox Code Playgroud)

我怎样才能获得这些信息?

c++ lambda template-meta-programming generic-lambda c++14

14
推荐指数
2
解决办法
461
查看次数

您在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
查看次数

Variadic模板功能:专门的头/尾和空基座

我想在类中有一个可变参数模板函数.可变参数模板参数是字符,应该以类似循环的方式处理.所以我想把它写成haskell,头部/尾部分割列表,直到达到基本情况(空列表).

举个例子,让我们只计算给出的参数数量(只是一个最小的例子).

我想出了以下代码:

struct MyClass {
    template<char ...X>
    static int count();
};


template<>
int MyClass::count<>() {
    return 0;
}
template<char Head, char ...Tail>
int MyClass::count<Head, Tail...>() {
    return 1 + count<Tail...>();
}
Run Code Online (Sandbox Code Playgroud)

但是,这似乎不起作用:

prog.cpp:12:35: error: function template partial specialization ‘count<Head, Tail ...>’ is not allowed
prog.cpp:12:5: error: prototype for ‘int MyClass::count()’ does not match any in class ‘MyClass’
prog.cpp:3:16: error: candidate is: template<char ...X> static int MyClass::count()
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?我知道功能不支持部分特化.但我认为将变量模板专门设计为头/尾和空基本案例版本不是局部专业化而是完全专业化,但也许我错了?我是否需要将其写为类而不是函数?

我发现了一些示例(printf),它们在不使用模板语法的情况下实现了基本情况.但我想我的情况有所不同,因为对printf的调用不使用模板语法而是类型推导,所以printf(tail...)调用printf() …

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

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

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
查看次数

我可以使用类型特征重载函数吗?

比方说,我有六种类型,它们各自属于一个概念类别.
这是一个显示这个的图表:

类型A,B和C包装在名为


或者也许是一个更具体的例子: Apple,Orange和Banana都是Fruit. 胡萝卜,洋葱和卷心菜都是蔬菜


我想编写两个函数来处理所有6种类型.
"类别1"中的类型以某种方式处理,"类别2"中的类型以不同的方式处理.

让我们进入代码.首先,我将创建六种类型.

//Category 1 Types
class Type_A{};
class Type_B{};
class Type_C{};

//Category 2 Types
class Type_D{};
class Type_E{};
class Type_F{};
Run Code Online (Sandbox Code Playgroud)

接下来,我将创建两个类型特征,以便可以在编译时发现类型的类别.

/* Build The Category 1 Type Trait */

//Type_A Type Trait
template <typename T>
struct Is_Type_A {
  static const bool value = false;
};
template <>
struct Is_Type_A<Type_A> {
  static const bool value = true;
};

//Type_B Type Trait
template <typename T>
struct Is_Type_B {
  static const bool value = false;
};
template <>
struct …
Run Code Online (Sandbox Code Playgroud)

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

13
推荐指数
2
解决办法
1321
查看次数

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
查看次数