c++ - Почему remove_reference не работает с функциями?




templates types (2)

Добро пожаловать в мир отвратительных типов функций.

void() & не является ссылкой на void() . Способ записи по буквам void(&)() (который, если вы remove_reference_t , вы получите обратно void() - то есть remove_reference_t работает со ссылками на функции, если то, что вы предоставляете, на самом деле является ссылкой на тип функции ).

На самом деле void() & ссылается на тип ссылочной функции-члена после того, как вы удалите класс. То есть:

struct C {
    void f() &;
};

Тип &C::f void (C::*)() & . Но все указатели на члены могут быть записаны как TC::* для некоторого типа T , и в этом случае тип T будет void() & .

Смотрите также P0172 .

Сталкивался с чем-то странным, когда делал какой-то шаблонный метапрограммирование на днях. Это в основном сводится к тому, что утверждение не (как я и ожидал) не прошло.

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

Сначала я думал, что допустил синтаксическую ошибку при определении ссылки на функцию, но это утверждение проходит, показывая, что это не так.

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

Я также попытался реализовать remove_reference копируя исходный код из cppreference, но это тоже не сработало. Что здесь происходит?


Тип, который вы имеете, - это не ссылка на функцию, а функция с квалификатором ссылки .

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(&)()>>);






c++17