【问题标题】:Are type aliases used as type of function parameter part of the function signature?类型别名是否用作函数签名的函数参数类型的一部分?
【发布时间】: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{});
}

[namespace.udecl]/15

当使用声明将名称从基类带入派生类时 类范围、成员函数和成员函数模板 派生类覆盖和/或隐藏成员函数和成员 具有相同名称的函数模板,参数类型列表, 基类中的 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


【解决方案1】:

A::fooB::foo

  • 同名 (foo)
  • 参数类型列表 (T !!!)
  • cv-qualification(不是const,不是易变的)
  • 引用限定符(无)

不考虑模板参数列表。

基类中的方法不是虚拟的,所以隐藏而不是覆盖。

Demo,参数类型列表是T

【讨论】:

  • 所以你是说在参数类型列表中考虑时别名必须替换为底层类型,而别名的附加模板参数无关紧要?
  • 顺便说一句,对于Demo,我不知道哪个编译器是正确的,如果有的话。
  • 又一个有趣的example 这次在第一个模板别名参数中使用了sfinae...这真的会产生相同的签名吗?!
  • @W.F.:我会说它们具有相同的参数类型列表,但 SFINAE 仍然适用于分辨率。
  • 好的,但是我们可以使别名本身依赖于参数,同时仍然可以扣除 T,例如 this。我们刚刚欺骗了编译器/标准吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-09
  • 2012-09-14
  • 1970-01-01
相关资源
最近更新 更多