如何从枚举索引类型的静态成员中获取对象的向量?

How to obtain a vector of object from static member of types indexed by enum?

提问人:StructSeeker 提问时间:11/5/2023 最后编辑:user12002570StructSeeker 更新时间:11/6/2023 访问量:74

问:

我有一个枚举类型和一个由它索引的类型。

enum class E{
    a, b, c, d, ..., count
};

template<E e>
class C{
};

template<>
class C<E::a>{
    static int fn(){
        return 1;
    };
};
// ... similar definition for E::b, E::c

如何编写一个函数来返回一个静态向量,其中包含由枚举索引的每个成员?也许使用可变参数模板?

const static std::vector<const std::function<int(void)>>& 
return_array(){
static std::vector<const std::function<int()>> a;
...
return a;
}
C++ 模板

评论

0赞 user12002570 11/5/2023
引用不是 C++ 中的对象,因此不能有引用数组。
1赞 user12002570 11/5/2023
“我该如何获得一组参考......”你不能。
0赞 user12002570 11/5/2023
此外,需要两个模板参数,而在您的示例中,您只给出/提供了 1。std::array
0赞 user12002570 11/6/2023
不要在已经有答案后完全更改问题,以免使答案无效。它浪费了人们的时间和精力来给出/写下答案。您可以提出一个新的单独问题。

答:

0赞 user12002570 11/5/2023 #1

首先注意,我们不能在C++中使用数组(或向量等)引用。您可以使用(请参阅方法 1)。std::cref

其次,需要两个模板参数,而在代码中只提供了一个。std::array

因此,为了解决这个问题,删除引用并传递第二个参数 2,如下所示。另请注意,有多种方法可以做你想做的事。&std::array

方法 1

这里我们使用 .std::cref

static std::array<std::function<int()>,3>  
return_array()
{
    //use std::cref
    static std::array<std::function<int()>,3> a{std::cref(C<E::a>::fn), std::cref(C<E::b>::fn), std::cref(C<E::c>::fn)}; 
    return a;   
} 

工作演示

方法 2

在这里,我们只删除引用,因为我们不能有引用的数组或向量。&

//-----------------------------------------v----->removed reference from here
static std::array<const std::function<int()>,3>  
//-------------------------------------------^--->pass the second argument
return_array()
{
    static std::array<const std::function<int()>,3> a{&C<E::a>::fn, &C<E::b>::fn, &C<E::c>::fn };
    return a;   
}

工作演示


方法 3

另一种替代方法是使用普通指针来运行。

//use normal pointer to function
static std::array<int(*)(),3>  return_array()
{
    static std::array<int(*)(),3> a{&C<E::a>::fn, &C<E::b>::fn, &C<E::c>::fn };
    return a;   
} 

演示


还有静态关键字及其在C++中的各种用法

评论

0赞 Jesper Juhl 11/5/2023
虽然我们不能有引用的向量,但我们可以有指针或 s 的向量。这可能对OP有用。std::reference_wrapper
0赞 user12002570 11/5/2023
@JesperJuhl 是的,我添加了(在方法 1 中)。现在有三种方法可以解决这个问题,所有这些都显示在答案中。std::cref