Remove_reference işlevler üzerinde neden çalışmıyor?


38

Geçen gün bazı metaprogramlama yaparken garip bir şeyle karşılaştım. Temelde bu iddiayı aşağıya (beklediğim gibi) geçmiyor.

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

İlk başta bir işlev referansı tanımlayan sözdizimsel bir hata yaptığımı sanıyordum, ancak bu iddia geçerliliğini koruyor.

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

Ayrıca remove_referencecppreference kaynak kopyalamak kendimi uygulamayı denedim ama bu da işe yaramadı. Burada neler oluyor?

Yanıtlar:


42

İğrenç İşlev Türleri dünyasına hoş geldiniz.

void() &olduğu olmayan bir referans void(). Yolu olurdu büyü void(&)()eğer hangi ( remove_reference_t, geri alacağı void()olduğunu - remove_reference_t does sen aslında işlev türü için bir referans sağlamak ne olur, işlevlerine referanslar üzerinde çalışmaya).

Ne void() &aslında atıfta Sınıfa kapalı şerit sonra bir referans nitelikli eleman fonksiyonunun türüdür. Yani:

struct C {
    void f() &;
};

Tipi &C::fDİR void (C::*)() &. Ama üyelerine tüm işaretçileri olarak yazılabilir T C::*bazı türü için T, ve bu durumda tip Tolacaktır void() &.

Ayrıca bkz . P0172 .


3
Birisi iğrenç işlev türleri için kanonik bir soru yaratmalıdır.
Brian

Vay canına, C ++ neredeyse 10 yıldır öğrenip kullansam bile beni asla şaşırtmadı.
Kelvin Hu

13

Sahip olduğunuz tür bir işleve başvuru değil, başvuru niteleyicisine sahip bir işlevdir .

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(&)()>>);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.