gpt4 book ai didi

c++ - 在编译时将枚举与模板类相关联

转载 作者:行者123 更新时间:2023-11-28 05:26:47 25 4
gpt4 key购买 nike

我有一个模板类如下:

template<typename A> struct TaskInfo{
typedef A _A;
static void bar(A a){blah blah...} };

template <typename TaskInfo> class Task {
typedef typename TaskInfo::_A A;
bar(A a){
blah blah...
TaskInfo::bar(a);
}
}

我有一个包含这些类集合的对象:

using TaskInfoX= TaskInfo<int>; //ignore the bar implementation for the time being.
using TaskInfoY= TaskInfo<double>;

class TaskCollection(){
TaskCollection(){
auto Task1=new Task<TaskInfoX>;
auto Task2=new Task<TaskInfoY>;
Register(Task1);
Register(Task2);
}
Register(...);
}

我想知道是否可以定义枚举列表:

enum TaskEnum
{
Etask1,
Etask2
};

和函数 getTask 这样在我的应用程序中我可以拥有:

int main {
TaskCollection collection;
int testInt;
double testDouble;
collection.getTask(Etask1)->bar(testInt);
//collection.getTask(Etask1)->bar(testDouble); //want compile error.
collection.getTask(Etask2)->bar(testDouble);
}

我知道我可以拥有 CRTP 或虚拟继承等价物,允许我为 bar() 传递可变参数,但我想在编译时对 bar 函数的参数进行类型检查。这在 C++ 中是不可能的吗?

更新:为打字错误道歉。这本来是:getTask(task1)。基本上,外界并不知道任务的底层结构,只能根据它们的公共(public)枚举 key 了解它们。另请注意,通常会有额外的任务可能会重用 typeInfoX 参数。

最佳答案

首先,要在类型不完全匹配时出现错误,您可以使用以下命令:

template <typename T>
class Task
{
public:
using type = typename T::type;

void bar(type a) { T::bar(a); }

template <typename U>
std::enable_if_t<!std::is_same<std::decay_t<U>, type>::value>
bar(U&&) = delete;
};

然后,在一些助手的帮助下:

template <TaskEnum> struct TaskMap;

template <> struct TaskMap<Etask1> { using type = Task<TaskInfoX>; };
template <> struct TaskMap<Etask2> { using type = Task<TaskInfoY>; };

您的收藏可能是这样的:

class TaskCollection
{
public:
Task<TaskInfoX> taskX;
Task<TaskInfoY> taskY;

template <TaskEnum E>
typename TaskMap<E>::type&
getTask();
};

template <>
Task<TaskInfoX>& TaskCollection::getTask<Etask1>() { return taskX; }

template <>
Task<TaskInfoY>& TaskCollection::getTask<Etask2>() { return taskY; }

最终用法:

collection.getTask<Etask1>().bar(testInt);
collection.getTask<Etask1>().bar(testDouble);//error:call to deleted member function 'bar'
collection.getTask<Etask2>().bar(testDouble);

Demo

关于c++ - 在编译时将枚举与模板类相关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40407375/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com