标签: template-meta-programming

可以根据模板参数有条件地添加 C++ 元组元素类型吗?

我正在尝试根据一些编译时条件有条件地将类型添加到元组模板类型,如下所示:

template <typename T>
class Base { ... }

template <int I>
class Derived : public Base<std::tuple<std::conditional<I % 8 == 0, int,    void>::type,
                                       std::conditional<I % 4 == 0, double, void>::type,
                                       std::conditional<I % 2 == 0, float,  void>::type>>
{ ... }

Run Code Online (Sandbox Code Playgroud)

我知道这不是有效代码,但从概念上讲,我试图有条件地将类型添加到元组列表中。我希望在条件解析为void.

有没有办法做这样的事情?

c++ tuples template-meta-programming

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

推动MPL占位符和Lambda

我目前正在使用boost :: mpl对概念样本进行一些证明,并且在理解lambda函数如何使用占位符方面遇到了一些困难.

我意识到我可以将metafunctions包装在元函数类中,以使更高阶函数能够访问嵌套的apply函数,并且已经意识到你可以通过使用mpl :: lambda包装允许占位符的元函数来避免这种努力.

这实际上是如何工作的?我无法将我的头包裹在lamda和占位符实际上在封面下做什么.

c++ lambda boost boost-mpl template-meta-programming

11
推荐指数
1
解决办法
1527
查看次数

C++类型特性,用于在T1和T2之间进行选择

我希望模板根据某些条件从两种类型中进行选择.例如

struct Base {};

template <typename T1, typename T2>
struct test
{
    // e.g. here it should select T1/T2 that is_base_of<Base>
    typename select_base<T1, T2>::type m_ValueOfBaseType;
};
Run Code Online (Sandbox Code Playgroud)

当然,将条件传递给select_base(使其通用)会很有用,但硬编码的解决方案也更容易和更好.

这是我尝试过的示例解决方案,但总是选择T1:http://ideone.com/EnVT8

问题是如何实现select_base模板.

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

11
推荐指数
2
解决办法
3523
查看次数

自动计算TMP中实例化类的数量?

给定模板元程序(TMP),C++编译器是否会生成计算实例化类数的构建统计信息?或者有没有其他方法可以自动获取此号码?因此对于例如对立的因子

#include <iostream>

template<int N> struct fact { enum { value = N * fact<N-1>::value }; };
template<> struct fact<1> { enum { value = 1 }; };

int main()
{
    const int x = fact<3>::value;
    std::cout << x << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我想回到数字3(因为事实<3>,事实<2>,事实<1>被实例化).这个例子当然是微不足道的,但每当你开始使用例如Boost.MPL时,编译时间真的会爆炸,我想知道有多少是由于隐藏的类实例化造成的.我的问题主要是针对Visual C++,但是gcc的答案也会受到赞赏.

编辑:我目前非常脆弱的Visual C++方法是从Stephan T. Lavavej的视频/d1reportAllClassLayout 之一添加编译开关,并在输出文件上执行grep +字数,但它(a)极大地增加了编译时间,并且(b)正则表达式很难100%正确.

c++ templates counter instantiation template-meta-programming

11
推荐指数
1
解决办法
1219
查看次数

带引用和静态类成员的奇怪案例

采取以下代码:

#include <type_traits>
#include <iostream>

template <class T>
void print(T &&t){
    std::cout << t << std::endl;
}

template<class T, T val>
struct Foo{
    static constexpr T value = val;
};

int main(){
    print(Foo<int, 123>::value);
}
Run Code Online (Sandbox Code Playgroud)

它拒绝在Clang 3.3和GCC 4.8.1下编译("undefined reference to Foo<int, 123>::value"),这让我感到困惑,因为Foo它完全相同std::integral_constant,并且相同的代码运行良好integral_constant.它也在打印功能中使用普通左值引用失败.有关此行为的任何解释?

这个极小的例子也出现了这个问题:

template<class T>
struct Bar{
    static const bool value = true;
};
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming

11
推荐指数
1
解决办法
246
查看次数

在编译时解决河内的塔楼

我试图在编译时解决河内塔,但我发现了一个问题:

template<int src, int dst>
struct move_disc
{
    // member access will print src and dst
};

template<int n, int src, int tmp, int dst>
struct hanoi
{
    hanoi<n-1, src, dst, tmp> before;
    typename move_disc<src, dst>::lol disc;
    hanoi<n-1, tmp, src, dst> after;
};

template<int src, int tmp, int dst>
struct hanoi<0, src, tmp, dst>
{
    // recursive base case
};

hanoi<3, 1, 2, 3> go;
Run Code Online (Sandbox Code Playgroud)

不幸的是,上面的元程序只打印了6个而不是7个:

prog.cpp:11:39: error: no type named ‘lol’ in ‘struct move_disc<1, 3>’
prog.cpp:11:39: error: …
Run Code Online (Sandbox Code Playgroud)

c++ templates towers-of-hanoi template-meta-programming

11
推荐指数
1
解决办法
1074
查看次数

如何从模板参数包中删除类型?

我正在寻找一种方法来从模板参数包中删除(现在让我们说所有出现的)一个类型.最终结果将是一个如下所示的结构:

template<typename T, typename...Ts>
struct RemoveT
{
    using type = /* a new type out of Ts that does not contain T */
}
Run Code Online (Sandbox Code Playgroud)

假设边缘情况RemoveT<int, int>将通过返回来处理void(不在后面的代码中处理).我的初始设计看起来像这样:

// --------------------------------------------------------------
// 1. A "way" of typedefing variadic number of types ------------
template<typename...Ts>
struct pack { 
    using type = Ts; 
};
// --------------------------------------------------------------

// --------------------------------------------------------------
template<typename T, typename...Ts> struct RemoveT;

template<typename T, typename T1, typename...Ts>
struct RemoveT {
    using type = typename pack<T1, typename RemoveT<T, …
Run Code Online (Sandbox Code Playgroud)

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

11
推荐指数
2
解决办法
2321
查看次数

有模板调试器吗?

模板本身可以是程序.

是否有模板调试器,以便您可以逐步执行模板的"执行"?

这基本上必须是在compile/link/codegen期间完成的事情 - 并且不同于调试生成的程序.

即使在许多不能使用调试器的"原始"环境中,通常也可以进行"printf调试".甚至可以使用模板吗?

编辑:另一种思考方式就像C预处理器.生成"预处理"源代码(编译器实际编译的预处理器输出)通常非常有用 - 这可以让您了解宏的效果.等效的模板会很棒 - 让编译器输出非模板源代码,该源代码与模板化输入相对应.我认为最接近的是C++到C的翻译器.(那个comeau编译器不这样做吗?)

c++ template-meta-programming

11
推荐指数
1
解决办法
428
查看次数

如何在C++编译时应用if

我试图编写一个通用static_for实现,可以接受边界,增量函数和比较函数来运行循环.我一直在使用这个构造,其中简单的循环增加1.在这种情况下,通过简单地专注于IDX & END相等而很容易停止循环展开.

但是,当增量可以是任意整数时,不能保证IDX & END总是相等.该if条件仅在运行时计算.在下面的代码片段中,我试图专注于std::false_type停止递归.通过评估std::less函数(可以由用户替换任何其他评估)来构造integral_constant .不幸的是,此comparator功能也仅在运行时进行评估,因此编译器失败.有人可以建议如何使这个工作?

注意:使用C++ 11.

template <int idx, int end, typename eval, int count, typename comparator>
struct static_for_loop {
  template <typename Lambda, typename... Args>
  void operator()(const Lambda& function, Args... args) const {
    if (comparator()(idx, end)) {
      std::integral_constant<int, idx> i;

      function(i, args...);

      constexpr bool lesser = comparator()(idx + count, end);
      static_for_loop<idx + count, end, std::integral_constant<bool, lesser>, count,
                      comparator>()(function, args...);
    }
  }
}; …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-meta-programming

11
推荐指数
1
解决办法
1336
查看次数

在C ++中创建类型的类型列表组合

我试图创建一些工具来创建基于其他类型组合的类型列表。

可以说我们有三种类型

struct A{};
struct B{};
struct C{};
Run Code Online (Sandbox Code Playgroud)

我想获得一个元组列表,其中包含N,A,B或C个类型的所有可能组合。

对于N = 2的情况,这将是

std::tuple<A,A>
std::tuple<A,B>
std::tuple<A,C>
std::tuple<B,A>
std::tuple<B,B>
std::tuple<B,C>
std::tuple<C,A>
std::tuple<C,B>
std::tuple<C,C>
Run Code Online (Sandbox Code Playgroud)

这个想法是创建一个元组来容纳所有这些类型的容器,因此我以后可以在容器列表中存储任何这些类型。

template <typename ...Combinations>
using CombinationList = std::tuple<std::vector<Combinations>...>;
Run Code Online (Sandbox Code Playgroud)

我已经有一种机制可以在适合的容器中插入一个特殊的元素,但是我对如何创建组合一无所知。

在人们建议使用的评论上std::vector<Combination<std::variant<A,C,B>, std::variant<A,B,C>>>。尽管这从技术上解决了问题,但我不喜欢使用它,因为A,BC的大小非常不同,并且我不想在运行时访问变体。另外,在某些时候,我需要将所有数据上传到

std::tuple<std::vector<Combination>...>
Run Code Online (Sandbox Code Playgroud)

到GPU,所以我不能在这里使用std :: variant。

我该怎么办?

谢谢!

PD:这与一个问题有关(一个枚举值(729个组合...)的组合爆炸)。 在这个问题中,我问我如何轻松生成将放入容器内的类型。现在我需要生成容器。

c++ cartesian-product template-meta-programming variadic-templates c++14

11
推荐指数
2
解决办法
804
查看次数