【发布时间】:2019-03-29 10:24:49
【问题描述】:
我了解,不会在依赖基类模板上执行对依赖 member/typedef 的查找,并且对于基成员,我必须显式添加前缀 this->member,或者在使用 typename base<T...>::sometype typedef/using 在基类上。
我能找到的所有答案都建议使用typename base<T...>::sometype。这显然可以是派生类中的 typedef,例如 using base_type = base<T...>,然后是 typename base_type::some_type,但这需要在派生和 typedef 中重复基类参数。
但是,当我使用derived::sometype,而不是指定基类时,它似乎确实有效。 for example
template <typename T>
struct base
{
using type = T*;
};
template <typename T>
struct derived : base<T>
{
derived ()
{
typename derived::type l; // <- Here
}
};
int main() {
derived <int> v;
return 0;
}
这允许我使用injected class name,并且重要的是,我可以在除类定义和基派生之外的任何地方保存模板参数的任何重复。
在this 的回答中,在我看来,编译器只需要知道该名称是一个依赖名称,以便在第二阶段进行查找,并且使用派生名称似乎是为了这个目的?
正如我发现的所有答案都建议使用 base<T...> 作为依赖名称,我很想知道使用 injected class name 访问基础中的依赖类型是否有任何问题?
编辑:
看起来基类名称也被注入了,所以
using base_type = derived::base; 是为了不必重复基类类型所需要的一切。至少在基类名称已知的情况下。
有趣的是,2009 年有一个 proposal 可以为基类起别名,这将解决当基类的名称不知道或继承自同一基类的多个特化时的问题。尽管该提案被拒绝,并说“鼓励论文作者继续朝着更通用的解决方案的方向前进”。
在其他地方讨论这个问题时,有人建议这样的事情会提供一个更通用的解决方案,并允许给碱基起别名并使用它们的注入名称。然而,据我所知,这还没有被提出。
template <typename T> using TD = typename std::decay<T>, using std::swap
void fun(TD x) noexcept(swap(x, x)) { ... }
【问题讨论】: