小编pre*_*eys的帖子

从包中获取所有子包

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

声明受保护的功能朋友

是否A::foo需要公开B宣布为朋友?

class A {
    protected:  // public ?
        void foo(int x);
};

class B : public A {
    friend void A::foo(int);  // not fine with GCC 4.8.1 but fine with VS 2013
    void goo(int x) {foo(x);}  // fine
    static void hoo(int x) {}
};

void A::foo(int x) {B::hoo(x);}  // friend declaration needed for this
Run Code Online (Sandbox Code Playgroud)

如果A :: foo受到保护,Visual Studio 2013认为没问题,但GCC 4.8.1认为它不是,并希望它是公开的.哪个编译器正确?我最初的直觉是它可以被宣布为受保护.毕竟,B是从A派生的,所以应该可以访问A :: foo(因为B :: goo简单地演示).

c++ function protected friend

5
推荐指数
1
解决办法
205
查看次数

与shared_ptr的神秘崩溃

有人可以解释为什么当内部范围退出时,main()中的以下崩溃?我正在使用Visual Studio 2013.虽然GCC 4.8.1的一切都很好,但我怀疑代码中有问题.我只是不明白.

#include <iostream>
#include <memory>

class Person;  class PersonProxy;

class PersonInterface {
    public:
        virtual ~PersonInterface() = default;
        virtual PersonProxy* getProxy() const = 0;
        virtual void createProxy (Person*) = 0;
    };

class Person : public PersonInterface {
    private:
        std::string name;
        std::shared_ptr<PersonProxy> proxy;
    public:
        Person() = default;
        explicit Person (const std::string& n) : name(n) {}
    public:
        virtual PersonProxy* getProxy() const override {return proxy.get();}
        inline void createProxy (Person* p);
};

class PersonProxy : public PersonInterface {
    private:
        std::shared_ptr<Person> actual;
    public: …
Run Code Online (Sandbox Code Playgroud)

c++ shared-ptr

5
推荐指数
2
解决办法
4934
查看次数

如何返回嵌套在其他包中的模板包?

以下代码有效:

#include <iostream>
#include <list>

struct Base {};
struct A : Base {};  struct B : Base {};  struct C : Base {};
struct D : Base {};  struct E : Base {};  struct F : Base {};

template <int KEY, typename... RANGE> struct Map {};  // one-to-many map (mapping KEY to RANGE...)

template <typename...> struct Data {};

using Database = Data<  Map<0, A,B,C>, Map<1, D,E,F>  >;

template <int N, typename FIRST, typename... REST>  // N has meaning in my …
Run Code Online (Sandbox Code Playgroud)

c++ templates pack variadic-templates c++11

5
推荐指数
1
解决办法
225
查看次数

部分专业化的朋友声明

在以下代码中:

template <typename U, typename V> class A {};
template <typename U, typename V> class B {};

template <typename T>
class C {
    template <typename U, typename V> friend class A;  // Works fine.
//  template <typename U> friend class B<U,T>;  // Won't compile.
};
Run Code Online (Sandbox Code Playgroud)

我想B<U,T>成为朋友C<T>,也就是说,B的第二个参数必须与C的参数匹配,尽管它的第一个参数可以是任何参数.我该如何实现这一目标?朋友的声明A<U,V>太多了,但如果我不能再限制它,我会接受.

也许定义一个元功能

template <typename, typename = void> struct FriendTraits { struct type{}; };

或类似的东西在C?

前2行

template <typename, typename = void> struct FriendTraits { struct type{}; };
template <typename U> …
Run Code Online (Sandbox Code Playgroud)

c++ templates friend

5
推荐指数
0
解决办法
780
查看次数

带有部分参数包的Variadic辅助函数

在以下代码中:

#include <iostream>

struct Base {
    virtual ~Base() = default;
    template <typename T, typename... Args> void helper (void (T::*)(Args..., int), Args...);
    void bar (int n) {std::cout << "bar " << n << std::endl;}
};

struct Derived : Base {
    void baz (double d, int n) {std::cout << "baz " << d << ' ' << n << std::endl;}
};

template <typename T, typename... Args>
void Base::helper (void (T::*f)(Args..., int), Args... args) {
    // A bunch on lines here (hence the …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic variadic-templates c++11

5
推荐指数
3
解决办法
413
查看次数

有人解释为什么这里有歧义,拜托?

Fill<T, Pack, Size, Value>是类型Pack<Value, Value, ..., Value>,其中值重复大小时间.有人可以解释,为什么这是模棱两可的?

template <typename T, template <T...> class Pack, int Size, int Count, typename Output, T Value>
struct FillHelper;

template <typename T, template <T...> class P, int Size, int Count, T... Output, T Value>
struct FillHelper<T, P, Size, Count, P<Output...>, Value> :
    FillHelper<T, P, Size, Count + 1, P<Output..., Value>, Value> {};

template <typename T, template <T...> class P, int Size, T... Output, T Value>
struct FillHelper<T, P, Size, Size, P<Output...>, Value> …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-templates c++11

5
推荐指数
1
解决办法
200
查看次数

用于几个组件的指数技巧

考虑这个完全有效的代码:

#include <type_traits>

template <typename T, typename IndexPack> struct Make;

template <typename T, template <T...> class P, T... Indices>
struct Make<T, P<Indices...>> {
    using type = P<(Indices+1)..., (-3*Indices)..., (Indices-1)...>;
};

template <int...> class Pack;

int main() {
    static_assert (std::is_same<Make<int, Pack<1,2,3,4>>::type, 
        Pack<2,3,4,5, -3,-6,-9,-12, 0,1,2,3>>::value, "false");
}
Run Code Online (Sandbox Code Playgroud)

我真正想要的输出是什么

Pack<2,-3,0, 3,-6,1, 4,-9,2, 5,-12,3>
Run Code Online (Sandbox Code Playgroud)

而不是Pack<2,3,4,5, -3,-6,-9,-12, 0,1,2,3>.我第一次尝试

using type = P<(Indices+1, -3*Indices, Indices-1)...>;
Run Code Online (Sandbox Code Playgroud)

但编译器简单地将其理解为无用的逗号运算符.得到我想要的东西的理想语法是什么?如果没有这样的语法,最简洁的方法是什么,请记住,使用Indices3次只是一个例子(我们可能想要使用它超过3次).请不要告诉我,我必须写一个助手来提取单个包,然后"交织"所有元素.这种噩梦般的方法不是最好的解决方案(只有当我们确切地知道要提取多少个包时,这样的解决方案才有效).

会定义

template <typename T, template <T...> class P, T I>
struct Component {
    using type = …
Run Code Online (Sandbox Code Playgroud)

c++ templates indices variadic-templates c++11

5
推荐指数
1
解决办法
344
查看次数

聪明的尖destructor电话传染媒介

为什么在下面的代码中只调用一次Node析构函数而不是5次?

#include <iostream>
#include <vector>
#include <memory>

struct Node {
    ~Node() {std::cout << "Node destructor called.\n";}
};

void foo() {
    std::vector<std::shared_ptr<Node>> nodes(5, std::make_shared<Node>());
}

int main() {
    foo();
    std::cout << "foo() ended.\n";
}
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers c++11

5
推荐指数
1
解决办法
229
查看次数

递归结束时的模板语法错误

有人能告诉我下面的递归特化结束语法有什么问题吗?我以为我遵守了所有的规则.

#include <iostream>

template <typename StreamType = std::ostream, StreamType& stream = std::cout>
class StringList {
    template <typename...> class AddStrings;
  public:
    template <typename... Args> void addStrings (Args&&... args) {AddStrings<Args...>()(args...);}
};

template <typename StreamType, StreamType& stream>
template <typename First, typename... Rest>
class StringList<StreamType, stream>::AddStrings<First, Rest...> : AddStrings<Rest...> {
public:
    void operator()(First&& first, Rest&&... rest) {
        // do whatever
        AddStrings<Rest...>::operator()(std::forward<Rest>(rest)...);
    }
};

template <typename StreamType, StreamType& stream>
template <>
class StringList<StreamType, stream>::AddStrings<> {
    friend class StringStreamList;
    void operator()() const {}  // End of …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11

4
推荐指数
1
解决办法
102
查看次数