我正在编写一个非常简单的模板类,使用元编程在编译时计算总和,如下所示:
#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 <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:
sum.cpp:9:14:错误:模板实例化深度超过1024的最大值(使用-ftemplate-depth …
考虑以下程序:
#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助手有重新排序的元组类型,使得两个元与萨姆斯的类型,但有序的不同导致相同的元组类型:它可以是第一个,第二个,甚至是另一个问题:它只是有相同的大小,相同的元素,但以一个独特的顺序(无论这个顺序如何).
是否可以使用模板元编程技术在编译时执行此操作?
我需要知道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++中看到的最酷的元编程实例是什么?
您在C++中看到的元编程有哪些实际用途?
可能重复:
从迭代器获取const_iterator
我想写一元函数返回相应的const_iterator从iterator
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类型.我认为这是一个合理的假设,虽然理论上并不完全正确.
我想在类中有一个可变参数模板函数.可变参数模板参数是字符,应该以类似循环的方式处理.所以我想把它写成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
我只是注意到Scala有宏,但我从未见过任何使用它们的代码.它们似乎与C预处理器宏等完全不同.通过阅读宏的概述,看起来它们看起来不像以前在Scala中提供的任何东西.在动机标题下,有一个宏启用的事项列表:
- 语言虚拟化(原始编程语言的重载/覆盖语义,以实现DSL的深度嵌入),
- 程序具体化(为程序提供检查自己代码的方法),
- 自我优化(基于程序实现的特定于域的优化的自我应用),
- 算法程序构造(使用编程语言支持的抽象编写繁琐的代码).
稍后在菜单中,有实验宏功能,例如类型宏,quasiquotes,无类型宏等等.显然需要这个!
对于那些构建非常复杂的库并且对Scala有深刻理解的人来说,所有这些看起来都很不错.但是宏也为普通的Scala开发人员提供了一些东西吗?使用宏会使我的Scala代码变得更好吗?
这是另一个问题的后续行动.它指的是同样的问题(我希望),但使用一个完全不同的例子来说明它.原因是在前面的示例中,只有实验性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
比方说,我有六种类型,它们各自属于一个概念类别.
这是一个显示这个的图表:

或者也许是一个更具体的例子:

我想编写两个函数来处理所有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) 我想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编译器不支持的时间吗?