具有相关值的模板特化

时间:2016-01-03 01:23:16

标签: c++ templates class-template

使用数组大小​​的模板似乎很简单:

template <size_t N>
struct MyArray
{
    char array[N];
};

但是,我想要做的是根据其他内容设置数组大小:

enum MyEnum {Hi, Lo};

template <MyEnum T, size_t N>
struct MyArray
{
    MyEnum type() { return T; }
    char array[N];
};

当MyEnum为Hi时如何将N设置为10,当MyEnum为Lo时如何设置200?

我想做的是说

MyArray<Lo> lo; // Result in MyArray<Lo, 200>
MyArray<Hi> hi; // Result in MyArray<Hi, 10>

而不是说

MyArray<Lo, 200> lo;
MyArray<Hi, 10> hi;

这可能吗?

2 个答案:

答案 0 :(得分:5)

您可以立即为==12085== Memcheck, a memory error detector ==12085== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==12085== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==12085== Command: ./main ==12085== ==12085== Invalid read of size 8 ==12085== at 0x401C61: Has_quarter_state::turn_crank() (in /home/mbw/Documents/Programmieren/CPP/Design_Patterns/Head_First_Design_Patterns/Chapter10_State_pattern/Example1_Revised/example_for_stackoverflow/main) ==12085== by 0x401730: Gumball_machine::turn_crank() (in /home/mbw/Documents/Programmieren/CPP/Design_Patterns/Head_First_Design_Patterns/Chapter10_State_pattern/Example1_Revised/example_for_stackoverflow/main) ==12085== by 0x402FF7: main (in /home/mbw/Documents/Programmieren/CPP/Design_Patterns/Head_First_Design_Patterns/Chapter10_State_pattern/Example1_Revised/example_for_stackoverflow/main) ==12085== Address 0x5e47048 is 8 bytes inside a block of size 16 free'd ==12085== at 0x4C2CE10: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==12085== by 0x4017B4: operator delete(void*, unsigned long) (in /home/mbw/Documents/Programmieren/CPP/Design_Patterns/Head_First_Design_Patterns/Chapter10_State_pattern/Example1_Revised/example_for_stackoverflow/main) ==12085== by 0x401858: Has_quarter_state::~Has_quarter_state() (in /home/mbw/Documents/Programmieren/CPP/Design_Patterns/Head_First_Design_Patterns/Chapter10_State_pattern/Example1_Revised/example_for_stackoverflow/main) ==12085== by 0x401B27: Has_quarter_state::turn_crank() (in /home/mbw/Documents/Programmieren/CPP/Design_Patterns/Head_First_Design_Patterns/Chapter10_State_pattern/Example1_Revised/example_for_stackoverflow/main) ==12085== by 0x401730: Gumball_machine::turn_crank() (in /home/mbw/Documents/Programmieren/CPP/Design_Patterns/Head_First_Design_Patterns/Chapter10_State_pattern/Example1_Revised/example_for_stackoverflow/main) ==12085== by 0x402FF7: main (in /home/mbw/Documents/Programmieren/CPP/Design_Patterns/Head_First_Design_Patterns/Chapter10_State_pattern/Example1_Revised/example_for_stackoverflow/main) ==12085== ==12085== ==12085== HEAP SUMMARY: ==12085== in use at exit: 0 bytes in 0 blocks ==12085== total heap usage: 3 allocs, 3 frees, 48 bytes allocated ==12085== ==12085== All heap blocks were freed -- no leaks are possible ==12085== ==12085== For counts of detected and suppressed errors, rerun with: -v ==12085== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) 设置默认值,与使用普通函数参数一样:

N

Live example

答案 1 :(得分:5)

你有几种可能性

直接在主类中使用N的计算:

template <MyEnum E>
class MyArray
{
    constexpr std::size_t N = (E == Hi ? 10 : 200);
public:
    MyEnum type() { return E; }
    char array[N];
};

或专门化

template <MyEnum E> struct MyArraySize;
template <> struct MyArraySize<Hi> : std::integral_constant<std::size_t, 10> {};
template <> struct MyArraySize<Low> : std::integral_constant<std::size_t, 200>{};

template <MyEnum E>
class MyArray
{
public:
    MyEnum type() { return E; }
    char array[MyArraySize<E>::value];
};