Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从多重继承确定模板包_C++_Templates_C++11_Inheritance - Fatal编程技术网

C++ 从多重继承确定模板包

C++ 从多重继承确定模板包,c++,templates,c++11,inheritance,C++,Templates,C++11,Inheritance,考虑以下代码: enum Brand {a,b,c,d,e,f,g,h,i,j}; template <Brand, int> struct A {}; struct B : A<a,4>, A<d,0>, A<i,3> {}; struct C : A<b,0>, A<c,5>, A<e,1>, A<h,4>, A<j,0> {}; template <typename, B

考虑以下代码:

enum Brand {a,b,c,d,e,f,g,h,i,j};

template <Brand, int> struct A {};

struct B : A<a,4>, A<d,0>, A<i,3> {};
struct C : A<b,0>, A<c,5>, A<e,1>, A<h,4>, A<j,0> {};

template <typename, Brand...> void foo() {}

int main() {
    foo<B, a,d,i>();
    foo<C, b,c,e,h,j>();
}
enum品牌{a,b,c,d,e,f,g,h,i,j};
模板结构A{};
结构B:A,A,A{};
结构C:A,A,A,A,A{};
模板void foo(){}
int main(){
foo();
foo();
}
foo()仅在我的(真实)程序中有意义,如果它有
a,d,i
作为参数。然而,
a,d,i
应该是可以推断的,否则如果我改变B的继承,就会有维护问题。这同样适用于
foo()


我一直在写
template struct GetBrands
以从
T
获取
Brand
元素的可推断包。任何帮助都将不胜感激。现在,让我们假设A中的最高int值是10。

好的,这里是我的第二个解决方案,用来替换第一个。通过引入a的基类,我现在允许算法工作,无论a有多少个模板参数(只要我们只关注a的第一个组件)。现在的解决方案也更短了

#include <iostream>
#include <type_traits>

enum Brand {a,b,c,d,e,f,g,h,i,j, FirstBrand = a, LastBrand = j};

template <Brand> struct HigherBase {};
template <Brand X, int> struct A : HigherBase<X> {};

struct B : A<a,4>, A<d,0>, A<i,3> {};
struct C : A<b,0>, A<c,5>, A<e,1>, A<h,4>, A<j,0> {};

template <typename T, Brand Current, typename Output> struct GetBrandsHelper;

template <typename T, Brand Current, template <Brand...> class P, Brand... Output>
struct GetBrandsHelper<T, Current, P<Output...>> :
    std::conditional<std::is_base_of<HigherBase<Current>, T>::value,
        GetBrandsHelper<T, static_cast<Brand>(Current + 1), P<Output..., Current>>,
        GetBrandsHelper<T, static_cast<Brand>(Current + 1), P<Output...>>
    >::type {};

template <typename Type> struct Identity { using type = Type; };

template <typename T, template <Brand...> class P, Brand... Output>
struct GetBrandsHelper<T, LastBrand, P<Output...>> :
    std::conditional<std::is_base_of<HigherBase<LastBrand>, T>::value,
        Identity<P<Output..., LastBrand>>,
        Identity<P<Output...>>
    >::type {};

template <Brand...> struct FooPack {};

template <typename T>
struct GetBrands : GetBrandsHelper<T, FirstBrand, FooPack<>> {};

//template <typename, Brand...>
//void foo() {}

// Specializing foo in order to test the outputs.
template <typename, Brand x, Brand y, Brand z>
void foo() {std::cout << x << ' ' << y << ' ' << z << '\n';}

template <typename, Brand x, Brand y, Brand z, Brand u, Brand v>
void foo() {std::cout << x << ' ' << y << ' ' << z << ' ' << u << ' ' << v << '\n';}

template <typename T, Brand... Is>
void fooHelper (const FooPack<Is...>&) {
    foo<T, Is...>();
}

template <typename T>
void bar() {
    fooHelper<T> (typename GetBrands<T>::type());
}

int main() {
    bar<B>();  // Supposed to be the same as foo<B, a,d,i>();  // 0 3 8
    bar<C>();  // Supposed be the same as foo<C, b,c,e,h,j>();  // 1 2 4 7 9
}
#包括
#包括
枚举品牌{a,b,c,d,e,f,g,h,i,j,FirstBrand=a,LastBrand=j};
模板结构HigherBase{};
模板结构A:HigherBase{};
结构B:A,A,A{};
结构C:A,A,A,A,A{};
模板结构GetBrandsHelper;
模板
结构GetBrandsHelper:
std::conditional::type{};
模板结构标识{using type=type;};
模板
结构GetBrandsHelper:
std::conditional::type{};
模板结构FooPack{};
模板
结构GetBrands:GetBrandsHelper{};
//模板
//void foo(){}
//专门化foo以测试输出。
模板

void foo(){std::cout如果我们将问题迎头痛击,(稍微)改变了编写
B
C
类定义的方式,会怎么样

下面,我从您的答案中借用了测试代码:

#include <iostream>

enum Brand {a,b,c,d,e,f,g,h,i,j};

template<Brand, int> struct A { };


template<typename...> struct A_base;
template<Brand... Brands, int... Is> struct A_base<A<Brands, Is>...> : A<Brands, Is>... { };


struct B : A_base<A<a,4>, A<d,0>, A<i,3>> { };
struct C : A_base<A<b,0>, A<c,5>, A<e,1>, A<h,4>, A<j,0>> { };

//template<typename, Brand...> void foo() { }

// *Overloading* foo in order to test the outputs.
template<typename, Brand x, Brand y, Brand z>
void foo() { std::cout << x << ' ' << y << ' ' << z << '\n'; }

template<typename, Brand x, Brand y, Brand z, Brand u, Brand v>
void foo() { std::cout << x << ' ' << y << ' ' << z << ' ' << u << ' ' << v << '\n'; }


template<typename S, Brand... Brands, int... Is> void foo_helper(A_base<A<Brands, Is>...>) 
{ 
    foo<S, Brands...>();
}

template<typename S> void bar() { foo_helper<S>(S()); }


int main()
{
    bar<B>();  // Supposed to be the same as foo<B, a,d,i>();  // 0 3 8
    bar<C>();  // Supposed be the same as foo<C, b,c,e,h,j>();  // 1 2 4 7 9
}
#包括
枚举品牌{a,b,c,d,e,f,g,h,i,j};
模板结构A{};
模板结构A_基础;
模板结构A_基:A..{};
结构B:A_基{};
结构C:A_基{};
//模板void foo(){}
//*重载*foo以测试输出。
模板

void foo(){std::cout是“品牌”s保证唯一?@T.C.很好。如果不是唯一的,我的算法确实会崩溃。所以我没有一个完整的通用解决方案。如果a有两个以上的模板参数,我的解决方案也会崩溃。这说明我的解决方案相当糟糕。我用我的新解决方案解决了上面提到的第二个问题,在这里我介绍了C重复的问题仍然存在。