【发布时间】:2017-10-18 07:53:59
【问题描述】:
考虑一个例子:
#include <iostream>
#include <vector>
template <class, class T>
using alias = T;
template <template <class...> class>
struct tt_wrapper{};
template <class...>
struct t_wrapper{};
struct A {
template <template <class...> class TT, class T>
void foo(alias<tt_wrapper<TT>, T>) { std::cout << "A::foo invoked" << std::endl; }
};
struct B: A {
using A::foo;
template <class U, class T>
void foo(alias<t_wrapper<U>, T>) { std::cout << "B::foo invoked" << std::endl; }
};
int main() {
B b;
b.foo<std::vector>(int{});
}
当使用声明将名称从基类带入派生类时 类范围、成员函数和成员函数模板 派生类覆盖和/或隐藏成员函数和成员 具有相同名称的函数模板,参数类型列表, 基类中的 cv-qualification 和 ref-qualifier(如果有)(而不是 比冲突)。
显然模板参数不应该参与成员函数隐藏。然而,在我们的示例中,模板参数使用别名被带到签名中。尽管如此,clang 似乎并不认同 alias 是函数 parameter-type-list 的一部分并声称:
prog.cc:26:7: error: no matching member function for call to 'foo'
b.foo<std::vector>(int{});
~~^~~~~~~~~~~~~~~~
prog.cc:21:10: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'U'
void foo(alias<t_wrapper<U>, T>) { std::cout << "B::foo invoked" << std::endl; }
^
1 error generated.
我故意省略了 gcc,因为它在隐藏过程中涉及模板参数列表。叮当是对的吗?
【问题讨论】:
-
@StoryTeller 我也这么认为...
-
是的,我明白了。我仍然停留在与“强 typedef”提案相结合的日子里。
-
我认为这应该被视为标准缺陷。与上一段相比,它为命名空间范围的函数模板指定返回类型和模板参数在确定 using 声明是否使程序格式错误方面确实很重要。
标签: c++ templates language-lawyer alias method-hiding