【问题标题】:Why doesn't remove_reference work on functions?为什么 remove_reference 对函数不起作用?
【发布时间】:2020-03-11 19:44:05
【问题描述】:

前几天在做一些模板元编程时遇到了一些奇怪的事情。它基本上归结为这个断言没有(如我所料)通过。

static_assert(std::is_same_v<void(), std::remove_reference_t<void()&>>);

起初我以为我在定义函数引用时犯了一个语法错误,但这个断言通过了,表明情况并非如此。

static_assert(std::is_same_v<void()&, void()&>);

我也尝试实现 remove_reference 自己从 cppreference 复制源代码,但这也不起作用。这是怎么回事?

【问题讨论】:

    标签: c++ templates types c++17


    【解决方案1】:

    欢迎来到可恶函数类型的世界。

    void() &amp;不是void()的引用。拼写方式是void(&amp;)()(如果你是remove_reference_t,你会得到void()——即remove_reference_t确实对函数的引用起作用,如果你提供什么它实际上是对函数类型的引用)。

    void() &amp; 实际上指的是剥离类后的引用限定成员函数的类型。那就是:

    struct C {
        void f() &;
    };
    

    &amp;C::f 的类型是void (C::*)() &amp;。但是对于某些类型T,所有指向成员的指针都可以写为T C::*,在这种情况下,T 类型将是void() &amp;

    另见P0172

    【讨论】:

    • 有人应该为可恶的函数类型创建一个规范问题。
    • 哇,即使我已经学习和使用了近 10 年的 C++,它也总是让我感到惊讶。
    【解决方案2】:

    您拥有的类型不是对函数的引用,而是带有reference qualifier 的函数。

    static_assert(std::is_same_v<void()&, void()&>);
    static_assert(!std::is_same_v<void()&, void(&)()>);
    static_assert(std::is_same_v<void(&)(), void(&)()>);
    static_assert(std::is_same_v<void(), std::remove_reference_t<void(&)()>>);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-13
      • 2014-08-06
      • 2015-02-20
      • 2021-08-20
      • 2021-07-25
      • 2013-08-26
      相关资源
      最近更新 更多