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) 是否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简单地演示).
有人可以解释为什么当内部范围退出时,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) 以下代码有效:
#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) 在以下代码中:
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) 在以下代码中:
#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) 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) 考虑这个完全有效的代码:
#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) 为什么在下面的代码中只调用一次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) 有人能告诉我下面的递归特化结束语法有什么问题吗?我以为我遵守了所有的规则.
#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)