小编pre*_*eys的帖子

这种模板语法是非法的吗?

我使用GCC 4.9.2得到了"内部编译器错误":

#include <type_traits>

template <typename T, typename, int, template <typename U, U, U> class>
struct Sort;

template <typename T, template <T...> class Z, T N, T... Is,
          template <typename U, U, U> class Comparator>
struct Sort<T, Z<N, Is...>, 0, Comparator> {
  template <T I>
  struct less_than : std::integral_constant<bool, Comparator<T, I, N>::value> {
  };
};

int main() {}
Run Code Online (Sandbox Code Playgroud)

错误消息指出:

c:\ ADandD> g ++ -std = c ++ 14 ComparatorAndSorterTGeneralized.cpp ComparatorAndSorterTGeneralized.cpp:254:80:内部编译器错误:在tsubst中,在cp/pt.c:11738

template<T I>
struct less_than : std::integral_constant<bool, Comparator<T,I,N>::value> {};
                                                                              ^
Run Code Online (Sandbox Code Playgroud)

如果合适,请提交完整的错误报告,并提供预处理的来源.有关说明,请参阅 …

c++ templates

35
推荐指数
1
解决办法
792
查看次数

Traversing a tree during compile time, with visiting actions

To make a preorder traversal of a nested pack of types (i.e. a tree of types), and then carry out an action at each leaf, I've worked out an algorithm already (and tested to work correctly):

template <typename T>
struct HasChildren : std::false_type {};

template <template <typename...> class P, typename... Types>
struct HasChildren<P<Types...>> : std::true_type {};

template <typename, typename> struct Merge;

template <template <typename...> class P1, template <typename...> class P2, typename... Ts, typename... Us>
struct Merge<P1<Ts...>, P2<Us...>> {
    using type …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11

30
推荐指数
1
解决办法
1144
查看次数

编译时间映射和反向映射值

有人可以推荐一种更优雅的方式来实现这些编译时常量吗?

template <int> struct Map;
template <> struct Map<0> {static const int value = 4;};
template <> struct Map<1> {static const int value = 8;};
template <> struct Map<2> {static const int value = 15;};

template <int> struct MapInverse;
template <> struct MapInverse<4> {static const int value = 0;};
template <> struct MapInverse<8> {static const int value = 1;};
template <> struct MapInverse<15> {static const int value = 2;};
Run Code Online (Sandbox Code Playgroud)

这个值需要在我的程序中是constexpr,但逆映射值更新很繁琐(容易出错或忘记做).

c++ meta templates map inverse

17
推荐指数
3
解决办法
1万
查看次数

传递许多函数并将所有结果存储在元组中

考虑这个输出:

int foo (int, char) {std::cout << "foo\n";  return 0;}
double bar (bool, double, long ) {std::cout << "bar\n";  return 3.5;}
bool baz (char, short, float) {std::cout << "baz\n";  return true;}

int main() {
    const auto tuple = std::make_tuple(5, 'a', true, 3.5, 1000, 't', 2, 5.8);
    multiFunction<2,3,3> (tuple, foo, bar, baz);  // foo  bar  baz
}
Run Code Online (Sandbox Code Playgroud)

因此,multiFunction<2,3,3>获取前2个元素tuple并将它们传递给foo接下来的3个元素tuple并将它们传递给bar等等...我得到了这个工作(除非函数有重载,这是一个单独的问题).但是所调用的每个函数的返回值都会丢失.我希望将这些返回值存储在某处,例如

std::tuple<int, double, bool> result = multiFunction<2,3,3> (tuple, foo, bar, baz);
Run Code Online (Sandbox Code Playgroud)

但我不知道如何实现这一点.对于那些想要帮助完成这项工作的人来说,这是我目前为止的(更新的)工作代码,它仅将输出存储到字符串流中.不容易获得所有值,特别是如果流中保存的对象是复杂类.

#include <iostream> …
Run Code Online (Sandbox Code Playgroud)

c++ templates tuples variadic c++14

10
推荐指数
1
解决办法
395
查看次数

可变模板:隔行扫描多个包

给定任意数量的包装,从每个包装中取出第一种类型,将它们放在一起.然后是每个包中的第二种类型,将它们放在一起等等......然后将它们全部合并.任何左撇子都会在他们之间重复这个过程.例如,使用整数表示不同类型以获得更好的可读性,

InterlacePacks<Pack<1 2 3 4>, Pack<5 6 7>, Pack<8 9 10 11 12>>::type
Run Code Online (Sandbox Code Playgroud)

会给

Pack<1 5 8 2 6 9 3 7 10 4 11 12>
Run Code Online (Sandbox Code Playgroud)

如果所有包只是相同的大小,则以下代码有效.我现在完全陷入对付"左结转"的时候,包是不同的尺寸.到目前为止,这是我的代码.我解释每个阶段,以便你知道我的计划是什么:

#include <iostream>

// First a helper to remove the first N types from a pack:
template <int, typename> struct RemoveHead;

template <typename Pack>
struct RemoveHead<0, Pack> { using type = Pack; };

template <template <typename...> class P, typename First, typename... Rest>
struct RemoveHead<0, P<First, Rest...>> { using type = …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic c++11

9
推荐指数
1
解决办法
763
查看次数

排序元素,但保持某些固定

功能

template <typename Container, typename Comparator, typename Predicate>
void sortButKeepSomeFixed (Container& c, const Comparator& comp, const Predicate& pred)
Run Code Online (Sandbox Code Playgroud)

c按照排序标准对容器进行排序comp,但满足的那些元素pred在排序后应保持固定在原始位置(即不受排序影响).

我试图适应快速排序以适应这一点,但无法想到它.最后,我决定调整原油选择排序来完成工作:

#include <iostream>
#include <vector>

std::vector<int> numbers = {5,7,1,8,9,3,20,2,11};

template <typename Container, typename Comparator, typename Predicate>
void sortButKeepSomeFixed (Container& c, const Comparator& comp, const Predicate& pred) {  // O(n^2), but want O(nlogn) on average (like quick sort or merge sort)
    const std::size_t N = c.size();
    std::size_t i, j, minIndex;
    for (i = 0; i < …
Run Code Online (Sandbox Code Playgroud)

c++ sorting lambda templates

7
推荐指数
1
解决办法
760
查看次数

检查类是否具有某个成员函数的其他方法

我们来看看是否

struct Thing {
    int foo(double, bool) {return 0;}
};
Run Code Online (Sandbox Code Playgroud)

int foo(double, bool)在编译期间有成员函数.有很多方法可以做到这一点,而且大多数只是其他方式的变体.有人会想到一种与我在这里提到的5种方式截然不同(或至少相当有创意)的方式吗?我只是想学习一些模板和SFINAE的新技术.

#include <iostream>
#include <type_traits>

// Using void_t (this includes using std::is_detected).
template <typename T>
using void_t = void;

template <typename T, typename = void>
struct has_foo : std::false_type {};

template <typename T>
struct has_foo<T,
        void_t<decltype(static_cast<int>(std::declval<T>().foo(double{}, bool{})))>
    > : std::true_type {};

// Using the ... default argument.
template <typename T>
struct hasfoo {
    template <typename U>
    static std::true_type test (decltype(static_cast<int(T::*)(double, bool)>(&T::foo))*);  // or 'decltype(static_cast<int>(std::declval<U>().foo(double{}, bool{})))*' works fine …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae c++11

7
推荐指数
1
解决办法
251
查看次数

带有可变参数模板参数的函数指针

参考下面的代码,有人可以弄清楚如何适应

template <typename RET, typename... ARGS1, typename... ARGS2>
RET Mediator::change (Object* o, RET (Object::*f)(ARGS1...), ARGS2&&... args) {
    const std::tuple<ARGS2...> t(args...);
    for (Object* x : objects)
        (x->*f)(std::get<0>(t), o->rating, std::get<1>(t), o->str);
}
Run Code Online (Sandbox Code Playgroud)

因此,每次更改ARGS2时,我都不必重写不同版本.我不介意在参数只包含4个参数的情况下这样做,但是你可以想象如果它远大于4则需要泛化.ARGS1中的类型......应该由不同的类型组成,所以应该有一种方法获得std :: get <0>(t),std :: get <1>(t),...正确放置,以便不需要像上面那样手动完成(即使有是重复类型,然后它们可以简单地放在重复类型的第一个插槽中).下面是完整的代码(上下文是,当Mediator的每个Object订阅者更改时,Mediator的其他Object订阅者应相应地更改):

#include <iostream>
#include <string>
#include <vector>
#include <tuple>

struct Mediator {
    std::vector<struct Object*> objects;

    void registerObject (Object* o) {objects.emplace_back(o);}

    template <typename RET, typename... ARGS1, typename... ARGS2>
    RET change (Object*, RET (Object::*)(ARGS1...), ARGS2&&...);
};

struct Object {
    int value;
    double rating;
    char letter;
    std::string …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic c++11

6
推荐指数
1
解决办法
795
查看次数

从包中获取所有子包

PowerSet<Pack<Types...>>::type是给出一个由所有子集形成的包组成的包Types...(现在假设静态断言,每个类型Types...都是不同的).例如,

PowerSet<Pack<int, char, double>>::type
Run Code Online (Sandbox Code Playgroud)

是的

Pack<Pack<>, Pack<int>, Pack<char>, Pack<double>, Pack<int, char>, Pack<int, double>, Pack<char, double>, Pack<int, char, double>>
Run Code Online (Sandbox Code Playgroud)

现在,我已经解决了这个练习并对其进行了测试,但我的解决方案很长,并希望听到一些更优雅的想法.我不是要求任何人审查我的解决方案,而是建议一个新的方法,或许用一些伪代码描绘他们的想法.

如果您想知道,这就是我所做的:首先,我从高中回忆起一组N个元素有2 ^ N个子集.每个子集对应于N位二进制数,例如001010 ... 01(N位长),其中0表示该元素在子集中,1表示该元素不在子集中.因此000 ... 0表示空子集,111 ... 1表示整个集合本身.因此,使用(模板)序列0,1,2,3,... 2 ^ N-1,我形成了2 ^ N个index_sequence,每个都对应于该序列中整数的二进制表示,例如index_sequence <1,1 ,0,1>将对应于该序列中的13.然后将那些2 ^ N index_sequence中的每一个转换为期望的2 ^ N个子集Pack<Types...>.

我的解决方案很长,我知道有一种比上面描述的机械方法更优雅的方法.如果你想到了一个更好的计划(也许更短,因为它更加递归或其他),请发表您的想法,以便我可以采取更好的计划,希望写出更短的解决方案.如果您认为可能需要一些时间(除非您愿意),我不希望您完整地写出您的解决方案.但是目前,我想不出比我做的更好的方式了.这是我目前的长期解决方案,如果你想阅读它:

#include <iostream>
#include <cmath>
#include <typeinfo>

// SubsetFromBinaryDigits<P<Types...>, Is...>::type gives the sub-pack of P<Types...> where 1 takes the type and 0 does not take the type.  The size of the two packs …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-templates c++11

6
推荐指数
2
解决办法
321
查看次数

带有默认模板参数的参数包

在这段代码中,我试图Test从 usingArg到 using进行概括Args...。问题是默认的模板参数。我在下面编译的内容,除非我取消注释 main() 中的注释行:

#include <iostream>
#include <type_traits>

struct A {
    void foo(int) const {}
    void foo(int, bool, char) const {}
};

template <typename...> struct voider { using type = void; };

template <typename... Ts>
using void_t = typename voider<Ts...>::type;

template <typename T, typename Arg, typename = void_t<T>>
struct Test : std::false_type {};

template <typename T, typename Arg>
struct Test<T, Arg, void_t<decltype(std::declval<T&>().foo(std::declval<Arg>()))>> :
    std::true_type {};

// Trying to generalize Test with Args... instead …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic c++11

6
推荐指数
1
解决办法
1322
查看次数

标签 统计

c++ ×10

templates ×10

c++11 ×6

variadic ×4

c++14 ×1

inverse ×1

lambda ×1

map ×1

meta ×1

sfinae ×1

sorting ×1

tuples ×1

variadic-templates ×1