【发布时间】:2021-01-15 06:08:15
【问题描述】:
简而言之:在一个以枚举类型作为参数的模板中(不是一个作用域枚举,一个常规的旧的 C++11 之前的枚举)我需要调用一个方法,声明在同一个struct 作为枚举,它以一个枚举值作为其参数。有没有办法做到这一点?
完整:假设我是“自我范围”的无范围枚举,如下所示:
struct W {
enum E { A, B, C };
static string foo(enum E e);
};
现在假设我有一堆遵循这种模式的结构声明 - 每个都有一个枚举 虽然枚举类型的 name 不同并且每个都有一个静态方法 @987654325 @ 采用该枚举类型的一个参数。
现在我想创建一个模板,给定一组这些枚举类型,希望根据自己的foo() 转换每个枚举类型:
template <typename E>
vector<string> xform(const vector<E> es) {
vector<string> ss;
for (E e : es) {
ss.push_back(foo(e));
}
return ss;
}
现在我实例化xform:
...
vector<enum W::A> as{W::A, W::C};
auto Wx = xform(as);
...
当然我得到一个编译器错误,因为编译器找不到正确的 foo 来调用:
prog.cc: In instantiation of 'std::vector<std::__cxx11::basic_string<char> > xform(std::vector<E>) [with E = W::A]':
prog.cc:34:24: required from here
prog.cc:24:21: error: 'foo' was not declared in this scope
24 | ss.push_back(foo(e));
| ~~~^~~
(这都是here on wandbox。)
所以我需要从枚举类型到它的对等方法。我可以这样做 - 怎么做? (由于对等方法的名称始终相同,所以这部分很简单——我不知道如何从枚举类型获取到它的封闭类型。)
(显然,如果每个结构中的枚举类型的 name 相同,我可以通过使用 struct's name 作为模板参数来解决这个问题。但在我的用例中枚举都有不同的名称。)
解决方案(此时):D-RAJ's answer 虽然非常简单,但在这种特殊情况下不起作用,因为函数 foo 不依赖于模板函数xform中的类型参数,因此与查找和ADL相关的规则以及模板中的非依赖名称意味着如果您尝试隐式实例化xform,则不能使用ADL不在其他命名空间的代码中。 (我不确定我理解为什么,但事实就是如此。)错误是在模板实例化点无法找到名称,只能在声明点(并且只能通过 ADL)找到。我想你可以通过显式实例化来解决这个问题......但是......
dxiv's answer 使用 trait 效果很好,并不繁琐,而且完全无需修改现有的封装枚举即可完成。
【问题讨论】: