【发布时间】:2018-02-05 22:58:39
【问题描述】:
我有以下代码:
#include <vector>
#include <array>
using std::vector;
enum EventType {
EventType_Collision,
EventType_Accelerate,
EventType_Glide
};
template<class T, EventType... events>
class A {
private:
static unsigned short CalcBitMask(EventType e) { return 1 << e; }
static constexpr unsigned short listeners = 0 | CalcBitMask(events)...;
protected:
//static constexpr int InternalGetType() { return 0; }
public:
static constexpr int GetType() { return T::InternalGetType(); }
static constexpr int GetListeners() { return listeners; }
};
class B : public A<B, EventType_Accelerate, EventType_Collision > {
friend class A<B, EventType_Accelerate, EventType_Collision>;
protected:
static constexpr int InternalGetType() { return 1; }
};
我正在尝试根据传递给模板的EvenType 参数创建一个位掩码。不幸的是,传递的EvenTypes 的数量是可变的。但是由于我们在编译时拥有所有参数,因此在编译时根据给定参数计算一个值似乎应该是更可能的constexpr。另一方面,我得到的是:
expression did not evaluate to a constant
对于 listeners 变量。有任何想法吗?提前致谢。
附:如果有人知道如何消除冗长的朋友类声明而不影响性能并保持 InternalGetType() 函数隐藏,我会很高兴并非常感谢听到它。
编辑
针对最近的一个建议,我仅限于使用 C++14
编辑
这就是我使用递归模板调用使其工作所做的工作 crtp.h
#pragma once
#include <vector>
#include <array>
using std::vector;
enum EventType {
EventType_Collision,
EventType_Accelerate,
EventType_Glide
};
template<class T, EventType... events>
class A {
private:
template <EventType Last>
static constexpr unsigned short BitCalc() {
return 1 << Last;
}
template <EventType First, EventType Second, EventType ...Rest>
static constexpr unsigned short BitCalc() {
return BitCalc<First>() | BitCalc<Second, Rest...>();
}
static constexpr unsigned short listeners = BitCalc<events...>();
protected:
//static constexpr int InternalGetType() { return 0; }
public:
static constexpr int GetType() { return T::InternalGetType(); }
static constexpr int GetListeners() { return listeners; }
};
class B : public A<B, EventType_Accelerate, EventType_Collision > {
friend class A<B, EventType_Accelerate, EventType_Collision>;
protected:
static constexpr int InternalGetType() { return 1; }
};
main.cpp
#include "ctrp.h"
#include <iostream>
#include <vector>
#include<bitset>
using std::cout;
using std::vector;
using std::getchar;
using std::endl;
int main() {
B b;
cout << "Bitmask: " << std::bitset<16>(b.GetListeners());
getchar();
return 0;
}
【问题讨论】:
标签: c++ c++14 variadic-templates template-meta-programming constexpr